这一章来讲一下配置单点登录
首先用到https协议,所以先用jdk自己的keytool工具来生成秘钥,所有输入密码的地方都用changeit 生成证书需要填入一些信息 最好有包含后面用到单点登录服务的域名 不然后面会报错证书中找不到那个域名
1:在d盘新建一个目录用来存放生成的证书文件d:/cas/keys
2:cmd下面进入到java_home 运行keytool -genkey -alias mycas -keyalg RSA -keysize 2048 -keystore d:/cas/keys/mycas.keystore
3.继续运行keytool -export -file d:/cas/keys/mycas.crt -alias mycas -keystore d:/cas/keys/mycas.keystore
导出证书;
4. keytool -import -keystore d:\Java\jdk1.7.0_60\jre\lib\security\cacerts -file d:/cas/keys/mycas.crt -alias mycas
其中:d:\Java\jdk1.7.0_60\jre\lib\security\cacerts为客户端JVM的密钥库位置
如果提示:
keytool error: java.io.IOException: Keystore was tampered with, or password was incorrect
删除d:\Java\jdk1.7.0_60\jre\lib\security\cacerts 在输入上述命令
5.配置tomcat服务端:
打开tomcat目录的conf/server.xml文件,8443端处,并设置keystoreFile、keystorePass修改结果如下:
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS"
keystoreFile="D:/cas/keys/mycas.keystore"
keystorePass="生成KEY的密码"
/>
参数说明:keystoreFile:在第一步创建的key存放位置 keystorePass:创建证书时的密码。
打开https://localhost:8443/,可以测试
6.cas-server-webapp-4.0.0.war拷贝到D:\apache-tomcat-7.0.54\webapps目录下,改名为cas.war(只是为了方便URL输入),并启动Tomcat, 会自动解压得到cas工程文件夹。
好了,现在打开浏览器,输入https://localhost:8443/cas/login 进入到cas登录的页面
7.
默认采用的username/password 在cas\WEB-INF下的deployerConfigContext.xml中是这样的:
<bean id="primaryAuthenticationHandler" class="org.jasig.cas.authentication.AcceptUsersAuthenticationHandler"> <property name="users"> <map> <entry key="casuser" value="Mellon"/> </map> </property> </bean>
输入username: casuser password:Mellon 登录成功
8.数据库为sso,里面有一个表t_member 中有username password字段
打开D:\apache-tomcat-7.0.54\webapps\cas\WEB-INF\deployerConfigContext.xml,
注释掉默认的用户验证,添加JDBC认证,代码如下:
<!--<bean id="primaryAuthenticationHandler" class="org.jasig.cas.authentication.AcceptUsersAuthenticationHandler"> <property name="users"> <map> <entry key="casuser" value="huiquan"/> </map> </property> </bean> --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" p:driverClass="com.mysql.jdbc.Driver"p:jdbcUrl="jdbc:mysql://127.0.0.1:3306/sso?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull" p:user="root" p:password="root" /> <!-- 密码加密方式--> <bean id="passwordEncoder" class="org.jasig.cas.authentication.handler.DefaultPasswordEncoder" c:encodingAlgorithm="SHA1" p:characterEncoding="UTF-8" /> <bean id="dbAuthHandler" class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler" p:dataSource-ref="dataSource" p:sql="select password from t_member where username=?" /> <!-- p:passwordEncoder-ref="passwordEncoder" --><!-- 暂时不使用密码加密 -->
根据上述配置,我们需要在D:\apache-tomcat-7.0.54\webapps\cas\WEB-INF\lib中加入c3p0-0.9.1.2.jar包、mysql-connector-java-5.1.21.jar包和cas-server-support-jdbc-4.0.0.jar包。
再修改D:\apache-tomcat-7.0.54\webapps\cas\WEB-INF\deployerConfigContext.xml中authentication manager的配置:
<bean id="authenticationManager" class="org.jasig.cas.authentication.PolicyBasedAuthenticationManager"> <constructor-arg> <map> <entry key-ref="proxyAuthenticationHandler" value-ref="proxyPrincipalResolver" /> <!--<entry key-ref="primaryAuthenticationHandler" value-ref="primaryPrincipalResolver" /> --> <entry key-ref="dbAuthHandler" value-ref="primaryPrincipalResolver"/> </map> </constructor-arg> <property name="authenticationPolicy"> <bean class="org.jasig.cas.authentication.AnyAuthenticationPolicy" /> </property> </bean>
再次运行Tomcat,访问https://localhost:8443/cas/login就能进行数据库验证了。
这里在本地映射一个127.0.0.1 www.ssomain.com 把loalhost换掉 不然完了出问题 这个域名和生成证书用的那个一样
9.CAS Client 配置
创建两个webgongc sso1 sso2
本地映射127.0.0.1 www.sso1.com 把下面配置文件中客户端的localhost换掉,sso2也一样 服务器端换成www.ssomain.com
本文中客户端工程部署在同一个Tomcat中,所以CAS Server和Client的域名都为localhost。
在Client工程WEB-INF/lib下添加cas-client-core-3.2.1.jar包。
修改web.xml如下:
<!-- ======================== 单点登录/登出 ======================== --> <!-- 该过滤器用于实现单点登出功能,可选配置。 --> <filter> <filter-name>CAS Single Sign Out Filter</filter-name> <filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class> </filter> <!-- 该过滤器负责用户的认证工作,必须启用它 --> <filter> <filter-name>CAS Authentication Filter</filter-name> <filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class> <init-param> <param-name>casServerLoginUrl</param-name> <param-value>https://localhost:8443/cas/login</param-value> </init-param> <init-param> <param-name>serverName</param-name> <param-value>http://localhost:8080</param-value> </init-param> </filter> <!-- 该过滤器负责对Ticket的校验工作,必须启用它 --> <filter> <filter-name>CAS Validation Filter</filter-name> <filter-class>org.jasig.cas.client.validation.Cas10TicketValidationFilter</filter-class> <init-param> <param-name>casServerUrlPrefix</param-name> <param-value>https://localhost:8443/cas</param-value> </init-param> <init-param> <param-name>serverName</param-name> <param-value>http://localhost:8080</param-value> </init-param> <init-param> <param-name>redirectAfterValidation</param-name> <param-value>true</param-value> </init-param> </filter> <!-- 该过滤器负责实现HttpServletRequest请求的包裹, 比如允许开发者通过HttpServletRequest的getRemoteUser()方法获得SSO登录用户的登录名,可选配置。 --> <filter> <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name> <filter-class>org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class> </filter> <!-- 该过滤器使得开发者可以通过org.jasig.cas.client.util.AssertionHolder来获取用户的登录名。 比如AssertionHolder.getAssertion().getPrincipal().getName()。--> <filter> <filter-name>CAS Assertion Thread Local Filter</filter-name> <filter-class>org.jasig.cas.client.util.AssertionThreadLocalFilter</filter-class> </filter> <filter-mapping> <filter-name>CAS Single Sign Out Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>CAS Authentication Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>CAS Validation Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>CAS Assertion Thread Local Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <listener> <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class> </listener> <!-- ======================== 单点登录/登出结束 ======================== -->
现在运行Client工程,首次访问任一页面就会跳转到https://www.sso1.com:8443/cas/login进行认证。同时,把你的退出链接设置为:https://sso.wsria.com/cas/logout 即可实现单点推出
登录进去默认为这个站点的额index.jsp
退出可以用http://www.ssomain.com:8080/logout?service=http://www.sso1.com:8080
登录界面:casLoginView.jsp
登录成功:casGenericSuccess.jsp
登出界面:casLogoutView.jsp
完成前面的步骤,并不能得到我们理想的效果。例如,我们的目标是:
Client端index页面 -> CAS Server端login页面 -> 认证成功 -> Client端index页面,并显示欢迎信息。
但由于Client端有自己的登录验证拦截机制,效果却是这样的:
Client端index页面 -> CAS Server端login页面->认证成功 -> Client端login页面。
所以,我需要修改Client端的认证拦截/跳转页面。
前面的步骤以后,我们在Client端的HttpServletRequest中已经可以通过getRemoteUser()方法得到用户名了。
String username = request.getRemoteUser();
再据此修正控制器login页面跳转或拦截器就行了。
最后感谢这两篇博文的作者帮我大忙了:
http://www.itnose.net/detail/6639688.html
http://itindex.net/detail/51110-cas-4.0-%E7%99%BB%E5%BD%95