使用 CAS 在 Tomcat 中实现单点登录

来源:互联网 发布:毫州康美中药城淘宝店 编辑:程序博客网 时间:2024/06/05 06:16

1.  什么是单点登录?

单点登录(Single Sign On , 简称 SSO )是目前比较流行的服务于企业业务整合的解决方案之一, SSO 使得在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。CAS(Central Authentication Service)是一款不错的针对 Web 应用的单点登录框架,本文介绍了 CAS 的原理、协议、在 Tomcat 中的配置和使用,对于采用 CAS 实现轻量级单点登录解决方案的入门读者具有一定指导作用。


CAS 是 Yale 大学发起的一个开源项目,旨在为 Web 应用系统提供一种可靠的单点登录方法,CAS 在 2004 年 12 月正式成为 JA-SIG 的一个项目。CAS 具有以下特点:

  • 开源的企业级单点登录解决方案。
  • CAS Server 为需要独立部署的 Web 应用。
  • CAS Client 支持非常多的客户端(这里指单点登录系统中的各个 Web 应用),包括 Java, .Net, PHP, Perl, Apache, uPortal, Ruby 等。


好顶赞


再推荐一个关于单点登录配置介绍的博客,

IBM博文,很犀利啊

http://www.ibm.com/developerworks/cn/opensource/os-cn-cas/

 tomcat SSL的配置

http://www.oschina.net/question/12_23148          

 官方文档 权威啊  里面有很多demo和优秀的博客,很多博客都是从这里翻译来的

https://wiki.jasig.org/display/CASC/Home  

http://hi.baidu.com/mlkoismlhkbmsvq/item/cafb013227c4689bb80c03bb    

http://www.blogjava.net/Jack2007/archive/2008/04/10/191795.html   


本文还参考了 一下博客:

http://www.cnblogs.com/dycg/archive/2013/04/04/2999012.html

http://blog.csdn.net/wqmain/article/details/8562602




2.  测试环境

服务端:Windows XP+ JDK1.7 + Tomcat7

客户端:Windows XP+ JDK1.7 + Tomcat7

CAS 服务端版本为 3.5.0,对应客户端jar包版本为 3.2.1

CAS 下载地址:http://www.jasig.org/cas/download   这个是官方地址, 我一直进不去,我在CSDN下载的,可以使用


2.  服务器端怎么安装?

CAS Server 是一套基于 Java 实现的服务,该服务以一个 Java Web Application 单独部署在与 servlet2.3 兼容的 Web 服务器上,另外,由于 Client 与 CAS Server 之间的交互采用 Https 协议,因此部署 CAS Server 的服务器还需要支持 SSL 协议

一、     生成服务端密钥文件

登录服务器打开一个CMD窗口(开始菜单 -> 运行输入cmd后回车)并切换到tomcat安装目录下(如:c:\tomcat-cas),执行如下命令:

keytool -genkey -alias casserver -keypass demosso -keyalg RSA -keystore casserver.keystore -validity 365


执行后,可以看到tomcat安装目录下生成了一个casserver.keystore文件。如下图:


说明:-alias指定别名为casserver;-keyalg指定RSA算法;-keypass指定私钥密码;-keystore指定密钥文件名称为casserver.keystore;-validity指定有效期为365天。另外提示的输入keystore密码应与-keypass指定的相同;您的名字与姓氏是CAS服务器使用的域名(不能是IP,也不能是localhost),其它项随意填。

注意:服务器上如果有多个JDK,请确认环境变量中的JDK路径为tomcat所使用的JDK,如果不在环境变量中,也可切换到指定JDK的bin目录下执行命令;提示的输入keystore密码应与-keypass必须与指定的相同,否则后面tomcat启动会报IO异常(Cannot recover key)。


二、     生成服务端证书

根据以上生成的服务端的密钥文件可以导出服务端证书,执行以下命令:

keytool -export -alias casserver -storepass demosso -file casserver.cer -keystore casserver.keystore


执行后,可以看到tomcat安装目录下生成了一个casserver.cer文件。如下图:


说明:-alias指定别名为casserver;-storepass指定私钥为demosso;-file指定导出证书的文件名为casserver.cer;-keystore指定之前生成的密钥文件的文件名。

注意:-alias和-storepass必须为生成casserver.keystore密钥文件时所指定的别名和密码,否则证书导出失败,报如下错误:



三、     导入证书文件到cacerts 密钥库文件

导入以上生成的服务端的证书文件到一个cacerts密钥库文件,执行以下命令:

keytool -import -trustcacerts -alias casserver-storepass demosso  -file casserver.cer–keystore cacerts


执行后,可以看到tomcat安装目录下生成了一个cacerts文件。如下图:



如果java的安装目录有空格,执行这句会报错,  我的做法是先把jdk中的cacerts拷贝到根目录下,再执行export操作


四、     服务端Tomcat配置

在制作完成密钥文件、证书文件、密钥库文件后即可进行服务端Tomcat的配置。打开$CATALINA_HOME/conf/server.xml文件,注释掉如下代码段:

<Connector port="80"protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443"/>

并取消注释<Connectorport="8443" protocol="HTTP/1.1" SSLEnabled="true"…/>代码段,修改后如下:


说明:port一般为8443或443,最常用的是443端口(https默认端口),这样https方式访问的时候可以不加端口号(如:https://sso.demo.com/cas/login);keystoreFile为tomcat目录下的密钥文件;keystorePass为私钥密码;truststoreFile为生成的信任文件,如果此处不指定则默认为$JAVA_HOME/jre/lib/security/cacerts文件;其它属性默认即可。


五、     生成客户端密钥库文件

单向认证的客户端配置只需生成客户端信任文件caserts即可。首先将服务端生成的证书文件(之前生成的casserver.cer文件)复制到$JAVA_HOME/jre/lib/security下,然后打开CMD窗口切换到$JAVA_HOME/jre/lib/security下并执行命令:

keytool -import -trustcacerts -alias casclient -storepass ssoclient -file casserver.cer -keystore cacerts

注意:需要在G:\Java\jdk1.8.0_25\jre\lib\security目录下生成,在G:\Java\jre1.8.0_25\lib\security目录下生成无效,可能和本地的环境配置有关系。



执行后,可以看到$JAVA_HOME/jre/lib/security目录下生成了一个cacerts文件。如下图:


OK到这里 SSL协议配置完成了。如果显示密码错误,请使用 changeit ,这个是jdk默认的证书密码


二、安装server端

咱们需要下载 cas-server-3.4.10-release.zip,这个里面包含war包和lib包

解压cas-server-3.4.10-release.zip\cas-server-3.4.10\modules\cas-server-webapp-3.4.10.war并改名为 cas.war,然后放到tomcat webapp目录下,启动tomcat

访问: https://localhost:8443/cas/login



 

用户名密码: admin admin

提示单点登录成功

 

 

上面是最基本的单点登录,用户名和密码是写死在配置文件中,那么我们如何使用JDBC呢?


使用JDBC登录


打开cas\WEB-INF\deployerConfigContext.xml

其中92行的

view plaincopy to clipboardprint?
  1. <bean class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" />  

就是简单的用户名密码验证,在实际中是用不到的。删掉他。

然后添加JDBC认证,注册一个dataSource,注意添加的位置,应当添加到bean标签的同级,不然server端启动不了

view plaincopy to clipboardprint?
  1. <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://localhost:3306/cas_demo</value></property>   <property name="username"><value>root</value></property>   <property name="password"><value>123456</value></property></bean>  

在刚刚注释的bean位置添加jdbc的bean,这里还包含一个MD5加密

view plaincopy to clipboardprint?
  1. <bean id="MD5PasswordEncoder" class="org.jasig.cas.authentication.handler.DefaultPasswordEncoder">    <constructor-arg index="0">        <value>MD5</value>    </constructor-arg></bean> <bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">    <property name="dataSource" ref="dataSource"></property>    <property name="sql" value="select password from user where login_name=?"></property>    <property name="passwordEncoder" ref="MD5PasswordEncoder"></property></bean>  

有spring基础的一般都能看懂。 

然后复制cas-server-3.4.10-release.zip\cas-server-3.4.10\modules下的cas-server-support-jdbc-3.4.10.jar以及mysql数据库的mysql.jar到cas/WEB-INF/lib目录下

要注意的是,org.jasig.cas.authentication.handler.DefaultPasswordEncoder加密后的字符串是小写的32位MD5密钥。

到此服务端配置完成。


客户端配置


下载cas-client-XXX-release.zip

然后解压出cas-client-3.2.1-release.zip\cas-client-3.2.1\modules下的cas-client-core-3.2.1.jar,放入你的web项目lib目录中

假设我有这么一个项目:

现在,我要做的就是修改web.xml

view plaincopy to clipboardprint?
  1. <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://sso.demo.com/cas/login</param-value>   </init-param>   <init-param>     <param-name>renew</param-name>     <param-value>false</param-value>   </init-param>   <init-param>     <param-name>gateway</param-name>     <param-value>false</param-value>   </init-param>   <init-param>     <param-name>serverName</param-name>     <param-value>http://192.68.69.75:80</param-value>   </init-param></filter><filter><filter-name>CASValidation Filter</filter-name><filter-class>org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</filter-class>   <init-param>     <param-name>casServerUrlPrefix</param-name>     <param-value>https://sso.demo.com/cas</param-value>   </init-param>   <init-param>     <param-name>serverName</param-name>     <param-value>http://192.68.69.75:80</param-value>   </init-param>   <init-param>     <param-name>useSession</param-name>     <param-value>true</param-value>   </init-param>   <init-param>     <param-name>redirectAfterValidation</param-name>     <param-value>true</param-value>   </init-param></filter><filter>   <filter-name>CAS HttpServletRequest WrapperFilter</filter-name>   <filter-class>org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class> </filter> <filter>   <filter-name>LoginFilter</filter-name>   <filter-class>demo.filter.LoginFilter</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 WrapperFilter</filter-name>   <url-pattern>/*</url-pattern></filter-mapping><filter-mapping>   <filter-name>LoginFilter</filter-name>   <url-pattern>/*</url-pattern></filter-mapping>  

说明:LoginFilter内容一般为获取用户基本信息、菜单信息然后保存到session中;sso.demo.com为CAS服务器的域名,也就是之前使用keytool –genkey命令指定的“名字与姓氏”。若未申请域名,也可以本地模拟实现域名解析,编辑C:\WINDOWS\system32\drivers\etc\hosts文件添加:CAS服务器IP  sso.demo.com 即可),如下图:


注意:serverName属性值为客户端实际IP地址,可以为域名但绝不能为localhost!

1、   客户端程序单点退出功能,需要访问https://sso.demo.com/cas/logout,下面提供了一个示例,当点击退出按钮(或超链接)时,调用javascript方法ssoLogout()。ssoLogout()定义如下(可根据实际需求自行修改):

view plaincopy to clipboardprint?
  1. <scripttypescripttype="text/javascript">function ssoLogout(){    if(confirm('确定要退出系统吗?')){      top.location.href ='https://sso.demo.com/cas/logout?service='+location.protocol+'//'+location.host+location.pathname;    }}</script>  

上面讲的是CAS单独部署的情况,也就是与其它应用分开部署。但有些情况是CAS与其它应用部署到同一台机器同一个Tomcat(关键问题是使用同一个JDK),这种情况下,服务端Tomcat配置中的<Connector truststoreFile属性就要指定为jdk下的cacerts文件路径或者直接注释掉(默认会找$JAVAHOME\jre\lib\security\下的cacerts文件)。这样服务端和客户端是同一个,也就不必再根据服务端证书生成客户端密钥库文件了。


常见配置错误

1、  CAS服务端Tomcat启动后报错:Error initializing endpoint java.io.IOException: Cannot recover key

是由于生成服务端密钥文件时所指定的keypass与提示输入的“keystore密码”不一致。

2、  javax.servlet.ServletException: org.jasig.cas.client.validation.TicketValidationException:绁ㄦ牴'ST-2-hozuLnLtIVGeaD5yju0Y-cas'涓嶇鍚堢洰鏍囨湇鍔?

一般是由于客户端应用web.xml中配置的serverName属性值为localhost或CAS服务端cas-servlet.xml配置文件中的<bean logoutController/>没加p:followServiceRedirects="true"退出后重定向属性。

3、  SSLHandshakeException: java.security.cert.CertificateException: Nosubject alternative names present

是由于客户端应用web.xml配置中的casServerLoginUrl和casServerUrlPrefix两个URL属性的域名与证书中定义的不一致。

0 0
原创粉丝点击