设为首页 收藏本站
查看: 735|回复: 0

[经验分享] 在Tomcat中使用Yale CAS实现单点登陆(SSO) 文章合集

[复制链接]

尚未签到

发表于 2017-2-9 10:21:59 | 显示全部楼层 |阅读模式
  在Tomcat中使用Yale CAS实现单点登陆(SSO) 文章合集
  
  耶鲁大学开发的单点登录系统称为CAS(Central Authentication Server)被设计成一个独立的Web应用程序(cas.war)。它目前用几个Java Servlet作为实现并且通过一个Https服务器来运行。要使用单点登陆功能的Web应用作为CAS的一个客户端来运行。
  由于CAS使用Https协议,所以首先要知道如何在容器中配置SSL。Tomcat的SSL配置相对其它的容器较为简单,SSL配置完成后CAS服务器一般都能正常运行了。
  CAS的客户端以一个Web应用的Filter运行。当Web应用的某个功能被请求时,Filter就会拦截应用的URL,从而迫使用户到CAS服务器进行登陆。在所有不同的Web应用中,使用同一个CAS服务器进行登陆,即可达到单点登陆之目的。
  本文使用同一个Tomcat(版本Tomcat5.0.30)配置CAS服务器及客户端,分别在8443端口及8080端口。下面是在Tomcat中使用Yale CAS实现单点登陆的详细步骤:
  <!--[if !supportLists]-->1.  <!--[endif]-->安装CAS服务器
  <!--[if !supportLists]-->1.1.  <!--[endif]-->下载CAS发行包,下载地址:
  CAS 服务器: http://www.yale.edu/tp/cas/cas-server-2.0.12.zip
https://clearinghouse.ja-sig.org/wiki/download/attachments/924/cas-server-2.0.12.zip
  CAS 客户端: http://www.yale.edu/tp/cas/cas-client-2.0.11.zip
https://clearinghouse.ja-sig.org/wiki/download/attachments/827/cas-client-2.0.11.zip
  <!--[if !supportLists]-->1.2.     <!--[endif]-->将cas-server-2.0.12.zip解压,并将lib/cas.war拷贝到Tomcat的webapps下,测试CAS服务器是否发布正常,可以访问http://localhost:8080/cas/login出现登陆窗口。输入用户名密码(用户名=密码),出现登陆成功页面说明发布正常。
  <!--[if !supportLists]-->2.   <!--[endif]-->配置Tomcat使用https协议
  <!--[if !supportLists]-->2.1.     <!--[endif]-->使用Java自带的keytool命令,产生SERVER的证书
  D:\> keytool -genkey -alias my-alias-name -keyalg RSA -keystore keystore-file
  其中 my-alias-name 为别名,这行命令的作用是产生一个新的公共 / 私有钥匙对。 keystore-file 为存储钥匙和证书的文件。
  命令运行后,根据提示回答。注意在开始问“你的名字”或“DName”的时候,必须填写你服务器所在域名(在局域网中测试时,使用主机名或hosts文件中注册的域名,本机可以使用localhost)。
  <!--[if !supportLists]-->2.2.     <!--[endif]-->在Tomcat的8443端口配置SSL
  在 Tomcat_Path\conf\server.xml 文件中配置 SSL 的地方,增加如下配置:
  <Connector className="org.apache.coyote.tomcat5.CoyoteConnector"
  port="8443" minProcessors="5" maxProcessors="75"
  enableLookups="true" disableUploadTimeout="true"
  acceptCount="100" debug="0" scheme="https"
  secure="true">
  <Factory className="org.apache.coyote.tomcat5.CoyoteServerSocketFactory"
  keystoreFile="D:/keystore-file"
  keystorePass="password" clientAuth="false" protocol="TLS" />
  </Connector>
  其中,keystoreFile使用绝对路径,keystorePass为第3点输入的keystore密码。配置完成后,启动Tomcat,访问https://localhost:8443 ,访问成功说明SSL配置成功。也可以访问https://localhost:8443/cas/login
  <!--[if !supportLists]-->3.      <!--[endif]-->配置 CAS客户端
  以Tomcat中自带的Servlet examples应用为例,在Web应用中使用配置CAS客户端。
  <!--[if !supportLists]-->3.1.        <!--[endif]-->在Servlet examples应用里配置CAS客户端,需修改servlets-examples/WEB-INF/web.xml,在web.xml文件中,加入如下Filter配置:
  <filter>
  <filter-name>CASFilter</filter-name>
  <filter-class>edu.yale.its.tp.cas.client.filter.CASFilter</filter-class>
  <init-param>
  <param-name>edu.yale.its.tp.cas.client.filter.loginUrl</param-name>
  <param-value>https://localhost:8443/cas/login</param-value>
  </init-param>
  <init-param>
  <param-name>edu.yale.its.tp.cas.client.filter.validateUrl</param-name>
  <param-value>https://localhost:8443/cas/proxyValidate</param-value>
  </init-param>
  <init-param>         <param-name>edu.yale.its.tp.cas.client.filter.serverName</param-name>
  <param-value>localhost:8080</param-value>
  </init-param>
  </filter>
  <filter-mapping>
  <filter-name>CASFilter</filter-name>
  <url-pattern>/servlet/*</url-pattern>
  </filter-mapping>
  其中,第一,二个localhost都改成CAS服务器域名或主机名,第三个改成你servelt example应用域名或主机名,由于本文中CAS服务器与客户端在同一主机同一Tomcat上,所以都为localhost。若不在同一主机,则分别使用两主机的域名或主机名。
  <!--[if !supportLists]-->3.2.     <!--[endif]-->将cas-client-2.0.11.zip解压,把java/lib/casclient.jar拷贝到Tomcat的
  webapps/servlets-examples/WEB-INF/lib目录下(如果没有就建一个)
  <!--[if !supportLineBreakNewLine]-->
  <!--[endif]-->
  <!--[if !supportLists]-->3.3.     <!--[endif]-->导出SERVER的证书,用来给所有需要用到的客户端导入
  D:\> keytool -export -file myserver.cert -alias my-alias-name -keystore keystore-file
  <!--[if !supportLists]-->3.4.     <!--[endif]-->在客户端的JVM里导入信任的SERVER的证书,输入keystore密码时,注意现在的keystore为cacerts,而cacerts的初密码为changeit,而不是前面keystore-file的密码,所以要是没有改过cacerts密码应该输入changeit.
  D:\> keytool -import -keystore $JAVA_HOME/jre/lib/security/cacerts -file myserver.cert -alias my-alias-name
  其中,$JAVA_HOME改成JDK的绝对路径。
  <!--[if !supportLists]-->4.         <!--[endif]-->测试SSO
  启动Tomcat,访问 http://localhost:8080/servlets-examples/ ,随便执行一个servlet,系统会自动跳转到一个验证页面,随便输入一个相同的账号,密码,认证通过之后,就会访问到你点击的servlet了。
  
  CAS (Central Authentication Service)是Yale大学的ITS开发的一套JAVA实现的开源
  的SSO(single sign-on)的服务。
  这里用一个简单的例子来说明用CAS来实现单点登陆(SSO)。CAS java client2.1.1 在Tomcat5.5.16下bug的解决
  最近在项目中集成了CAS 结合Acegi来作单点登陆。感觉CAS虽然简单,用起来还是很爽的。不过前几天发布一个子系统的时候出现了下面的问题。
  edu.yale.its.tp.cas.client.CASAuthenticationException: Unable to validate ProxyTicketValidator
  < cas:authenticationFailure code = ' INVALID_SERVICE ' >
  ticket  ' ST-74-yBBJRjb3qnFle0Ynhq7sgUsdaox9nPoFbGu-20 '  does not match supplied service
  </ cas:authenticationFailure >
  
  经排查,发现是CAS java client2.1.1 与Tomcat 5.5.16配合有问题。查看log,发现Cas Server端解析出的service URL前后相差了一个“?”,怀疑是cas client在新版tomcat下生成 service URL时出现问题,检查client代码,定位到edu.yale.its.tp.cas.client.Util的getService方法,跟踪了一下,发现
  if  (request.getQueryString()  !=   null ) 
  {
  //  first, see whether we've got a 'ticket' at all
  int  ticketLoc  =  request.getQueryString().indexOf( " ticket= " );
  
  //  if ticketLoc == 0, then it's the only parameter and we ignore
  //  the whole query string
  
  //  if no ticket is present, we use the query string wholesale
  if  (ticketLoc  ==   - 1 )
  sb.append( " ? "   +  request.getQueryString());
  else   if  (ticketLoc  >   0 ) 
  {
  ticketLoc  =  request.getQueryString().indexOf( " &ticket= " );
  if  (ticketLoc  ==   - 1 ) 
  {
  //  there was a 'ticket=' unrelated to a parameter named
  //  'ticket'
  sb.append( " ? "   +  request.getQueryString());
  }   else   if  (ticketLoc  >   0 ) 
  {
  //  otherwise, we use the query string up to "&ticket="
  sb.append( " ? "
  +  request.getQueryString().substring( 0 , ticketLoc));
  }
  }
  }
  
  发现对于没有参数的http请求,request.getQueryString()函数在Tomcat5.5.15中是返回null,而5.5.16中是返回""。到这里问题就清楚了,看来yale的这帮学生代码写得还是有点业余呀,直接加上对空string判断的逻辑,问题解决。
  这个bug我已经提交到cas的jira上了,应该很快可以fix了,在新版本client没有发布前,可以使用附件压缩包中的jar替换casclient.jar。
  casclient.zip
  Yale CAS项目总结
  SSO总会有一个结束的时候,我最终把CAS Server 2.0放到Weblogic Portal上,并实现了到其他WebApp的单点登陆。困难比我原先想象的要大,总结几点,希望对来者有所帮助。
  1,搞SSO前请先熟悉SSL/PKI,因为,CAS的安全性很大程度依赖于SSL,没有安全性,不敢想象SSO有何作为。
  2,因为我们的环境是在Weblogic Portal上,Portal环境上,调试CAS费了我好大力气,加之我重写了CAS的LoginModule(CAS不提供J_Security_check登陆方式),中途抛出的错误很多,访问BEA Support网站是家常便饭了。
  3,CAS需要配置信任证书,如果象我那样一步一步地创建根CA,ServerCA,恐怕会比较辛苦,但证书的确让我高枕无忧,从CAS Server和各个Web应用之间建立一种更松耦合的信任关系。
  4,IE端到CAS Server的双向SSL虽是画蛇添足,但是在一些高安全性的SSO环境,如网上付费,付出少许的计算代价,即让身份欺诈无所遁形。
  冷静下来,想了一下SSO的用处,看来在互连星空中会有卖点,事实上,电信已经使用了SSO了,联通在信平台也在各SP与MISC之间部署SSO,随着B2B,B2C的发展,相信SSO会有很不错的前途。
  我个人对CAS的评价是,
  PureJava Impl,OpenSource,能轻松在各种WebServer间移植,协议并没有Kerberos那么复杂(当然Kerberos更安全),所以使用和调试起来,没有Kerberos那么痛苦。实战中,本人更倾向使用CAS 3.0,基于Spring的一种实现方式,将来有空必为此写一Blog.
  
使用cas实现sso
 
  CAS (Central Authentication Service)是Yale大学的ITS开发的一套JAVA实现的开源
  的SSO(single sign-on)的服务,http://www.yale.edu/tp/cas/
  cas分为服务端和客户端,在服务端开启SSL,服务器下发证书安装到各个客户端中,客户端在与服务器进行通讯验证时,将检验二者的证书是否一致。
  1、服务器中生成证书:keytool -genkey -alias cnc -keystore c:\mykeystore
  导出证书,由客户端安装: keytool -export -alias -keystore c:\mykeystore -file c:\mycerts.cer
  注:生成证书时,CN要和服务器的域名相同,如果在本地测试,则使用localhost
  2、客户端配置:(注:使用client2.0.11版本稳定些,2.0.10总报异常)
  将服务器下发的证书导入到JVM中
  keytool -import -trustcacerts -alias cnc -keystore $JAVA_HOME/JRE/LIB/SECURITY/CACERTS -file c:\mycert.cer
  (如果这样不行,则到JAVA_HOME/JRE/LIB/SECURITY/下进行)
  配置web.xml:
  <filter>
  <filter-name>CASFilter</filter-name>
  <filter-class>edu.yale.its.tp.cas.client.filter.CASFilter</filter-class>
  <init-param>
  <param-name>edu.yale.its.tp.cas.client.filter.loginUrl</param-name>
  <param-value>https://localhost:8443/cas/login</param-value>
  </init-param>
  <init-param>
  <param-name>edu.yale.its.tp.cas.client.filter.validateUrl</param-name>
  <param-value>https://localhost:8443/cas/proxyValidate</param-value>
  </init-param>
  <init-param>
  <param-name>edu.yale.its.tp.cas.client.filter.serverName</param-name>
  <param-value>localhost</param-value>
  </init-param>
  </filter>
  <filter-mapping>
  <filter-name>CASFilter</filter-name>
  <url-pattern>/*</url-pattern>
  </filter-mapping>
  
  当前CAS默认的用户名和密码判断是,只要用户名和密码相同即可。使用的类为SampleHandler,一般的是与数据库进行匹配,这样我们可以实现PasswordHandler接口, 在authenticate()方法中进行验证。可以在容器中配置数据源,使用容器提供的数据源。
  同时修改服务器下CAS的web.xml中的配置,使用自己的类。
  <context-param>
  <param-name>edu.yale.its.tp.cas.authHandler</param-name>
  <param-value>edu.yale.its.tp.cas.auth.provider.MyDBHandler</param-value>
  </context-param>
  然后重新BUILD,将类打包,替换服务器CAS/WEB-INF/LIB下原来的包。
  
  CAS只能提供SSO,对于角色,授权,则要在web.xml进行相应的配置<security-constraint>,也可以使用filter。
  
  常出现的异常:“未找到可信任的证书”--主要原因为在客户端未将服务器下发的证书导入到JVM中,可以用keytool -list -alias cnc -keystore $JAVA_HOME/JRE/LIB/SECURITY/CACERTS
  来查看证书是否真的导入到JVM中。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-339626-1-1.html 上篇帖子: 一个Tomcat支持不同的域名访问各自不同程序的配置方法 下篇帖子: Hibernate used with tomcat 5.5.x JNDI(来源于http://www.theserv)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表