CAS单点登入SSO配置说明

安装环境

常用命令

-genkey:在用户主目录创建一个默认文件“.keystore”,还会产生一个mykey的别名,makey中包含用户的公钥、私钥和证书
-alias:产生别名
-keystore:指定密钥库的名称
-keyalg:指定密钥的算法
-validity:指定创建证书有效期多少天
-keysize:指定密钥长度
-storepass:指定密钥库的密码
-keypass:指定别名条目的密码
-dname:指定证书拥有者信息
-list:显示密钥库中证书信息
-v:显示密钥库中证书的详细信息
-export:将别名指定的证书导出到文件
-file:参数指定导出的文件到文件名
-delete:删除密钥库中某条目
-keypasswd:修改密钥库中指定条目口令
-import:将已签名数字证书导入密钥库

创建证书

证书是单点登录认证系统中很重要的一把钥匙,客户端于服务器的交互安全靠的就是证书,这里使用JDK自带的keytools工具生成证书,

如果以后真正在产品环境中使用肯定要去证书提供商去购买。

用JDK自带的keytool工具生成证书:

keytool -genkey -alias cas -keyalg RSA -keystore f:/resources/cas



输入完信息之后,输入 y,然后输入密码,提交。

这里,由于我的名称输入的是sso.rying.com,其实这个域名是不存在的,修改

C:\Windows\System32\drivers\etc\hosts

添加内容如下:

127.0.0.1  sso.rying.com

这样在访问sso.rying.com的时候其实是访问的127.0.0.1也就是本机


导出证书

dos下进入f:/resources目录,

F:\resources>keytool -export -file f:/resources/cas.crt -alias wsria -keystore f:/resources/cas

输入密码,提交。



客户端JVM导入证书

keytool -import -keystore E:\develop\Java\jdk1.6.0_37\jre\lib\security\cacerts -file f:\resources\cas.crt -alias cas


如果发生错误

尝试使用密码 changeit

至此证书的创建、导出、导入到客户端JVM都已完成


应用到tomcat

修改tomcat,conf/server.xml文件
  1. <!-- Define a SSL HTTP/1.1 Connector on port 8443  
  2.          This connector uses the JSSE configuration, when using APR, the  
  3.          connector should be using the OpenSSL style configuration  
  4.          described in the APR documentation -->  
  5.       
  6.     <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"  
  7.                maxThreads="150" scheme="https" secure="true"  
  8.                clientAuth="false" sslProtocol="TLS" keystoreFile="F:/resources/cas" keystorePass="root123" />  

但是修改之后,发现tomcat启动报错:
[plain] view plain copy
  1. 严重: Failed to initialize end point associated with ProtocolHandler ["http-apr-8443"]  
  2. java.lang.Exception: Connector attribute SSLCertificateFile must be defined when using SSL with APR  
  3.     at org.apache.tomcat.util.net.AprEndpoint.bind(AprEndpoint.java:494)  
  4.     at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:610)  
  5.     at org.apache.coyote.AbstractProtocol.init(AbstractProtocol.java:429)  
  6.     at org.apache.catalina.connector.Connector.initInternal(Connector.java:981)  
  7.     at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)  
  8.     at org.apache.catalina.core.StandardService.initInternal(StandardService.java:559)  
  9.     at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)  
  10.     at org.apache.catalina.core.StandardServer.initInternal(StandardServer.java:814)  
  11.     at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)  
  12.     at org.apache.catalina.startup.Catalina.load(Catalina.java:633)  
  13.     at org.apache.catalina.startup.Catalina.load(Catalina.java:658)  
  14.     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)  
  15.     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)  
  16.     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)  
  17.     at java.lang.reflect.Method.invoke(Method.java:597)  
  18.     at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:281)  
  19.     at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:450)  
  20. 2013-2-19 10:30:25 org.apache.catalina.core.StandardService initInternal  
  21. 严重: Failed to initialize connector [Connector[HTTP/1.1-8443]]  
  22. org.apache.catalina.LifecycleException: Failed to initialize component [Connector[HTTP/1.1-8443]]  
  23.     at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:106)  
  24.     at org.apache.catalina.core.StandardService.initInternal(StandardService.java:559)  
  25.     at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)  
  26.     at org.apache.catalina.core.StandardServer.initInternal(StandardServer.java:814)  
  27.     at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)  
  28.     at org.apache.catalina.startup.Catalina.load(Catalina.java:633)  
  29.     at org.apache.catalina.startup.Catalina.load(Catalina.java:658)  
  30.     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)  
  31.     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)  
  32.     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)  
  33.     at java.lang.reflect.Method.invoke(Method.java:597)  
  34.     at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:281)  
  35.     at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:450)  
  36. Caused by: org.apache.catalina.LifecycleException: Protocol handler initialization failed  
  37.     at org.apache.catalina.connector.Connector.initInternal(Connector.java:983)  
  38.     at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)  
  39.     ... 12 more  
  40. Caused by: java.lang.Exception: Connector attribute SSLCertificateFile must be defined when using SSL with APR  
  41.     at org.apache.tomcat.util.net.AprEndpoint.bind(AprEndpoint.java:494)  
  42.     at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:610)  
  43.     at org.apache.coyote.AbstractProtocol.init(AbstractProtocol.java:429)  
  44.     at org.apache.catalina.connector.Connector.initInternal(Connector.java:981)  
  45.     ... 13 more  

原因是Tomcat提供了两个SSL实现,一个是JSSE实现,另外一个是APR实现。
Tomcat将自动选择使用哪个实现,即如果安装了APR则自动选择APR,否则选择JSSE。
6.0默认使用JSSE实现,而7.0则使用APR实现。所以修改server.xml
  1. <Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol" SSLEnabled="true"  
  2.                maxThreads="150" scheme="https" secure="true"  
  3.                clientAuth="false" sslProtocol="TLS" keystoreFile="F:/resources/cas" keystorePass="root123" />  

启动tomcat,一切正常,访问https://sso.rying.com:8443/,打开:

点击继续,进入tomcat欢迎页面,OK。

CAS服务器配置

下载完成后解压到 F:\resources,把 F:\resources\cas-server-3.5.1\modules\cas-server-webapp-3.5.1.war 重命名为cas.war,复制到tomcat webapp下面
访问 https://sso.rying.com:8443/cas/login,看到登入页面:

用户名密码相同就能登入成功了。 

CAS链接数据源登入配置

上面的初体验仅仅是简单的身份验证,实际应用中肯定是要读取数据库的数据,下面我们来进一步配置CAS服务器怎么读取数据库的信息进行身份验证。首先打开

tomcat/webapp/cas/WEB-INF/deployerConfigContext.xml

找到
  1. <bean class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" />  

把这个简单登入验证注释掉,修改

  1. <bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">   
  2.     <property name="dataSource" ref="dataSource"></property>   
  3.     <property name="sql" value="select password from user where username=?"></property>   
  4. </bean>  

最后在配置文件末尾前加上
  1. <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">  
  2.         <property name="driverClassName">  
  3.             <value>com.mysql.jdbc.Driver</value>  
  4.         </property>  
  5.         <property name="url">  
  6.             <value>jdbc:mysql://localhost:3306/test?autoReconnect=true&useUnicode=true&characterEncoding=utf-8</value>  
  7.         </property>  
  8.         <property name="username"><value>root</value></property>  
  9.         <property name="password"><value>root</value></property>  
  10.         <property name="defaultAutoCommit"><value>false</value></property>  
  11. </bean>  
表:
  1. -- ----------------------------  
  2. -- Table structure for `user`  
  3. -- ----------------------------  
  4. DROP TABLE IF EXISTS `user`;  
  5. CREATE TABLE `user` (  
  6.   `id` int(11) NOT NULL AUTO_INCREMENT,  
  7.   `username` varchar(100) DEFAULT NULL,  
  8.   `passwordvarchar(100) DEFAULT NULL,  
  9.   PRIMARY KEY (`id`)  
  10. ) ENGINE=InnoDB AUTO_INCREMENT=22 DEFAULT CHARSET=utf8;  
  11.   
  12. -- ----------------------------  
  13. -- Records of user  
  14. -- ----------------------------  
  15. INSERT INTO `userVALUES ('1''irwin''123');  
  16. INSERT INTO `userVALUES ('2''janey''456');  
  17. INSERT INTO `userVALUES ('3''harris''789');  
  18. INSERT INTO `userVALUES ('4''howard''110');  
  19. INSERT INTO `userVALUES ('5''morris''888');  
  20. INSERT INTO `userVALUES ('6''stephen''999');  
  21. INSERT INTO `userVALUES ('7''linsay''000');  
  22. INSERT INTO `userVALUES ('8''lilian''111');  
  23. INSERT INTO `userVALUES ('9''perry''666');  
  24. INSERT INTO `userVALUES ('10''laura''eeee');  
  25. INSERT INTO `userVALUES ('20''www''ddd');  
  26. INSERT INTO `userVALUES ('21''dd''dd');  

赋值 F:\resources\cas-server-3.5.1\modules\cas-server-support-jdbc-3.5.1.jar 到 tomcat/webapp/cas/WEB-INF/lib目录

这里由于我使用的DBCP数据源,需要加入相应的jar包,如果使用其他数据源,加入相应的jar包即可。

使用现在数据库存在的数据登入成功:



配置说明:

QueryDatabaseAuthenticationHandler:cas-server-support-jdbc提供的查询接口其中一个,QueryDatabaseAuthenticationHandler是通过配置一个 SQL 语句查出密码,与所给密码匹配。

如果需要使用密码加密,可以创建一个类继承 org.jasig.cas.authentication.handler.PasswordEncoder,然后在encode中加密用户输入的密码返回即可。

如果需要在代码中获取用户名密码进行验证,可以创建一个类继承 org.jasig.cas.authentication.handler.support.AbstractUsernamePasswordAuthenticationHandler,重写

authenticateUsernamePasswordInternal方法。

CAS客户端配置

eclipse下新建一个web项目,从F:\resources\cas-client-3.2.1\modules导入jar包
cas-client-core-3.2.1.jar
commons-logging-1.1.jar
配置web.xml,添加以下内容:
  1. <!-- 登出 -->  
  2.    <listener>  
  3.        <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>  
  4.    </listener>  
  5.      
  6.    <!-- 登出 ,改filter要在其他filter之前-->  
  7.    <filter>  
  8.        <filter-name>CAS Single Sign Out Filter</filter-name>  
  9.        <filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>  
  10.    </filter>  
  11.   
  12.    <!-- 用于单点登录拦截验证 -->  
  13.    <filter>  
  14.        <filter-name>CAS Authentication Filter</filter-name>  
  15.        <filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>  
  16.        <init-param>  
  17.            <param-name>casServerLoginUrl</param-name>  
  18.            <param-value>https://sso.rying.com:8443/cas/login</param-value>  
  19.        </init-param>  
  20.        <init-param>  
  21.            <param-name>serverName</param-name>  
  22.            <param-value>http://localhost:8080</param-value>  
  23.        </init-param>  
  24.    </filter>  
  25.      
  26.    <!-- 请求参数ticket验证(ticket即子系统与CAS系统进行交互的凭证) -->  
  27.    <filter>  
  28.        <filter-name>CAS Validation Filter</filter-name>  
  29.        <filter-class>org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</filter-class>   
  30.        <init-param>  
  31.            <param-name>casServerUrlPrefix</param-name>  
  32.            <param-value>https://sso.rying.com:8443/cas</param-value>  
  33.        </init-param>  
  34.        <init-param>  
  35.            <param-name>serverName</param-name>  
  36.            <param-value>http://localhost:8080</param-value>  
  37.        </init-param>  
  38.    </filter>  
  39.   
  40.    <!--  
  41.    该过滤器负责实现HttpServletRequest请求的包裹,  
  42.    比如允许开发者通过HttpServletRequest的getRemoteUser()方法获得SSO登录用户的登录名,可选配置。  
  43.    -->  
  44.    <filter>  
  45.        <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>  
  46.        <filter-class>org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class>  
  47.    </filter>  
  48.      
  49.    <!--  
  50.    该过滤器使得开发者可以通过org.jasig.cas.client.util.AssertionHolder来获取用户的登录名。  
  51.    比如AssertionHolder.getAssertion().getPrincipal().getName()。  
  52.    -->  
  53.    <filter>  
  54.        <filter-name>CAS Assertion Thread Local Filter</filter-name>  
  55.        <filter-class>org.jasig.cas.client.util.AssertionThreadLocalFilter</filter-class>  
  56.    </filter>  
  57.      
  58.     <filter-mapping>  
  59.        <filter-name>CAS Single Sign Out Filter</filter-name>  
  60.        <url-pattern>/*</url-pattern>  
  61.    </filter-mapping>  
  62.      
  63.     <filter-mapping>  
  64.        <filter-name>CAS Authentication Filter</filter-name>  
  65.        <url-pattern>/*</url-pattern>  
  66.    </filter-mapping>  
  67.      
  68.     <filter-mapping>  
  69.        <filter-name>CAS Validation Filter</filter-name>  
  70.        <url-pattern>/*</url-pattern>  
  71.    </filter-mapping>  
  72.   
  73.    <filter-mapping>  
  74.        <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>  
  75.        <url-pattern>/*</url-pattern>  
  76.    </filter-mapping>  
  77.      
  78.        <filter-mapping>  
  79.        <filter-name>CAS Assertion Thread Local Filter</filter-name>  
  80.        <url-pattern>/*</url-pattern>  
  81.    </filter-mapping>  


WebContent下创建测试页面,hello.html
启动服务器,浏览器访问 http://localhost:8080/CASClient/hello.html


页面跳转到CAS系统登入页面,输入用户名密码

登入成功,返回hello.html页面,并且带上了jsessionid。

注意:这里可能会抛出异常 sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
解决办法:导入证书到jre中,方法同导入到jdk中的jre。
keytool -import -keystore E:\develop\Java\jre6\lib\security\cacerts -file f:\resources\cas.crt -alias cas
看下是否添加成功:keytool -list -keystore E:\develop\Java\jre6\lib\security\cacerts


此时,再创建一个CASClient2,项目同CASClient,使用CASClient访问hello.html并且登入成功之后,我们访问CASClient2的hello.html

可以看到同样带上了jsessionid,登入成功。

访问 https://sso.rying.com:8443/cas/logout 测试注销,出现注销成功页面,OK。
如果注销成功想回到登入页面,可以修改cas-servlet.xml文件,在logoutController的bean配置中修改
p:followServiceRedirects="${cas.logout.followServiceRedirects:false} 为 true
修改 logout路径,并加上service属性,为需要重定向页面地址
原来路径:https://sso.rying.com:8443/cas/logout 
现在:https://sso.rying.com:8443/cas/logout ?service=http://localhost:8080/CASClient/login.html

界面美化

CAS服务器登入页面在\webapps\cas\WEB-INF\view\jsp\default\ui下
  • 登入页面:casLoginView.jsp
  • 登入成功页面:casGenericSuccess.jsp
  • 登出页面:casLogoutView.jsp
自己修改替换这些文件就可以了。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值