咱们先按套路来,上点客套的:html
一、CAS的基本工做原理java
二、CAS的时序图以下mysql
三、好吧好吧,下面废话不说,我直接来干货web
A、hosts文件的配置,无关紧要,可是按照我以前看别人的博客,这个仍是方便安全证书的生成的算法
C:\Windows\System32\drivers\etc\hosts 文件中添加三条spring
127.0.0.1 demo.tch.comsql
127.0.0.1 app1.tch.com数据库
127.0.0.1 app2.tch.comapache
demo.tch.com =>>对应部署cas server的tomcat,这个虚拟域名还用于证书生成
app1.tch.com =>> 对应部署app1的tomcat
app2.tch.com =>>对应部署app2的tomcat浏览器
B、生成安全证书
C:\Users\yang>keytool -genkey -alias ssodemo1 -keyalg RSA -keysize 1024 -keypass 123456 -keystore f:\sso\ssodemo.keystore -storepass 123456
keypass 和 storepass 两个密码要一致,不然下面tomcat 配置https 访问失败;
而后咱们将证书导出:
C:\Users\yang>keytool -export -alias ssodemo1 -keystore f:\sso\ssodemo.keystore -file f:\sso\ssodemo.crt -storepass 123456
有关keytool工具的详细运用见:http://www.micmiu.com/lang/java/keytool-start-guide/
C、进行服务端的配置,这个比较重要,并且也是浪费我时间最多的一个地方,由于网上的博客不少东西写的都不对,我也不知道他们是怎么实现的,我把个人弯路show给你看:
服务端tomcat配置文件 conf/server.xml文件进行以下修改:
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> <Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol" SSLEnabled="true" maxThreads="150" scheme="https" secure="true" keystoreFile="F:/Study/Java/Projects/SSO/Demo/keys/ssodemo.keystore" keystorePass="123456" clientAuth="false" sslProtocol="TLS" URIEncoding="UTF-8"/> <!-- Define an AJP 1.3 Connector on port 8009 --> <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> <Host name="demo.tch.com" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false">
对以上代码进行截图,而后对以上配置进行分析
CAS-Server下载地址:http://www.jasig.org/cas/download
本文以cas-server-3.4.11-release.zip为例,解压提取cas-server-3.4.11/modules/cas-server-webapp-3.4.11.war文件,把改文件copy到 G:\sso\tomcat-cas\webapps\目下,并重命名为:cas.war.
启动tomcat-cas,在浏览器地址栏输入:https://demo.tch.com:8443/cas/login ,回车
写这篇日志的时候,不少东西我都已经修改了,可是以上表示成功了,真实的图片容我给你盗个图来
CAS-server的默认验证规则:只要用户名和密码相同就认证经过(仅仅用于测试,生成环境须要根据实际状况修改),输入admin/admin 点击登陆,就能够看到登陆成功的页面:
看到上述页面表示CAS-Server已经部署成功。
上面的初体验仅仅是简单的身份验证,实际应用中确定是要读取数据库的数据,下面咱们来进一步配置CAS服务器怎么读取数据库的信息进行身份验证。 首先打开
cas/WEB-INF/deployerConfigContext.xml
注释掉:SimpleTestUsernamePasswordAuthenticationHandler这个验证Handler,这个是比较简单的,只是判断用户名和密码相同便可经过,这个确定不能在实际应用中使用,弃用!紧接着添加以下代码
<bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler"> <property name="dataSource" ref="dataSource"></property> <property name="sql" value="select password from t_admin_user where login_name=?"></property> <property name="passwordEncoder" ref="MD5PasswordEncoder"></property> </bean>
在文件的末尾以前加入以下代码:
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName"><value>com.mysql.jdbc.Driver</value></property> <property name="url"><value>jdbc:mysql:///wsriademo</value></property> <property name="username"><value>root</value></property> <property name="password"><value>root</value></property> </bean> <bean id="MD5PasswordEncoder" class="org.jasig.cas.authentication.handler.DefaultPasswordEncoder"> <constructor-arg index="0"> <value>MD5</value> </constructor-arg> </bean>
复制cas-server-3.4.3.1\modules\cas-server-support-jdbc-3.4.3.1.jar和mysql/Oracle驱动jar包到tomcat/webapp/cas/WEB-INF/lib目录
QueryDatabaseAuthenticationHandler,是cas-server-support-jdbc提供的查询接口其中一个,QueryDatabaseAuthenticationHandler是经过配置一个 SQL 语句查出密码,与所给密码匹配
dataSource,我就不用解释了吧,就是使用JDBC查询时的数据源
sql,语句就是查询哪一张表,本例根据t_admin_user表的login_name字段查询密码,CAS会匹配用户输入的密码,若是匹配则经过
而后修改cas/WEB-INF/cas.properties文件,修改以下两行,具体含义我就很少说了
server.name=http://demo.tch.com:8080 server.prefix=${server.name}/cas
D、客户端的配置
导入jar包
<dependency> <groupid>org.jasig.cas.client</groupid> <artifactid>cas-client-core</artifactid> <version>3.1.12</version> </dependency>
修改你客户端中的web.xml文件进行修改,添加filter
<!-- sso 单点登陆sso 单点登陆sso 单点登陆sso 单点登陆sso 单点登陆sso 单点登陆sso 单点登陆--> <listener> <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class> </listener> <!--该过滤器用于实现单点登出功能,可选配置。--> <!--<filter>--> <!--<filter-name>CAS Single Sign Out Filter</filter-name>--> <!--<filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>--> <!--</filter>--> <!--<filter-mapping>--> <!--<filter-name>CAS Single Sign Out Filter</filter-name>--> <!--<url-pattern>/*</url-pattern>--> <!--</filter-mapping>--> <filter> <filter-name>CASFilter</filter-name> <filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class> <init-param> <param-name>casServerLoginUrl</param-name> <param-value>http://demo.tch.com:8080/cas/login</param-value> </init-param> <init-param> <param-name>serverName</param-name> <param-value>http://app1.tch.com:18080</param-value> </init-param> </filter> <filter-mapping> <filter-name>CASFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!--该过滤器负责对Ticket的校验工做,必须启用它--> <filter> <filter-name>CASValidationFilter</filter-name> <filter-class> org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</filter-class> <init-param> <param-name>casServerUrlPrefix</param-name> <param-value>http://demo.tch.com:8080/cas</param-value> </init-param> <init-param> <param-name>serverName</param-name> <param-value>http://app1.tch.com:18080</param-value> </init-param> </filter> <filter-mapping> <filter-name>CASValidationFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 该过滤器负责实现HttpServletRequest请求的包裹, 好比容许开发者经过HttpServletRequest的getRemoteUser()方法得到SSO登陆用户的登陆名,可选配置。 --> <filter> <filter-name>CASHttpServletRequest WrapperFilter</filter-name> <filter-class> org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class> </filter> <filter-mapping> <filter-name>CASHttpServletRequest WrapperFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 该过滤器使得开发者能够经过org.jasig.cas.client.util.AssertionHolder来获取用户的登陆名。 好比AssertionHolder.getAssertion().getPrincipal().getName()。 --> <filter> <filter-name>CASAssertion Thread LocalFilter</filter-name> <filter-class>org.jasig.cas.client.util.AssertionThreadLocalFilter</filter-class> </filter> <filter-mapping> <filter-name>CASAssertion Thread LocalFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
注*此时app1的http端口号为1880,经过拦截来跳转到cas服务,cas服务经过了用户名和密码以后携带cas生成的tickets回到客户端。
在app1系统的intercepter拦截器中,根据AssertionHolder.getAssertion().getPrincipal().getName()取得当前登陆用户的用户名,来从本身的系统数据库中取得用户信息。同时在单独登陆系统时,也不会受到cas系统干扰。
User user = (User) session.getAttribute("admin"); if(null == user){ if(null != AssertionHolder.getAssertion()){ String userName = AssertionHolder.getAssertion().getPrincipal().getName(); if(null != userName || !"".equals(userName)){ user = userService.queryUserByuserName(userName); } } }
E、预期流程:打开app1 url —->跳转cas server验证 —->显示app1的应用 —->打开app2 url —->显示app2应用 —->注销cas server —->打开app1/app2url —->从新跳转到cas server验证.
F、
CAS服务端(cas-server)的界面只能在测试的时候用一下,真正系统上线确定须要定制开发本身的页面,就像网易和CSDN的统一认证平台同样,全部子系统的认证都经过此平台来转接,你们能够根据他们的页面本身定制出适合所属应用或者公司的界面;简单介绍一下吧,复制 cas\WEB-INF\view\jsp\default\ui的一些JSP文件,每个文件的用途文件名已经区分了,本身修改了替换一下就能够了。 例如:
参考资料:http://www.2cto.com/os/201402/281465.html
http://www.kafeitu.me/sso/2010/11/05/sso-cas-full-course.html