单点登陆框架CAS的研究

CAS作为开源的单点登陆框架已经非常的流行了。由于它对已有系统的入侵性小,支持的语言多,备受广大开发者关注;也是很多公司将之作为单点登陆的首选框架。关于CAS如何搭建的文章,网上已经非常多了,随便搜搜都一大堆。我也就不再写些重复的东西了,但是网上的东西有时候常常是不全,或版本问题搞的很多人都很迷糊。我曾经也很迷糊,如果刚接触CAS,请你继续往下看;如果你是CAS高手,请指正我说错的地方。

CAS最早是耶鲁大学开发的(CAS2.0以前的版本),后来开源出来由JASIG来继续开发(CAS2.0以后的版本)。所以,当你准备那某一片文章上手练习的时候请分清版本。个人建议还是阅读JASIG官方文档比较好。https://wiki.jasig.org/display/CASC

一个完整的单点登陆方案分两部分

CAS server

CAS server如何配置就不多说了,基本的步骤就是

1. 下载CAS server包

2. 配置Tomcat的Https访问设置

3. 部署CAS server,其实就是将.war文件拷贝到Tomcat目录下

4. 生成证书(可以买,也可以使用自签名证书,或者干脆就用http协议,那就不需要证书了)

5. 修改用户访问配置(CAS支持关系数据库,LDAP等多种数据存储)

 

CAS client

CAS client是部署在应用端的,因为通常单点登陆都会涉及到对已有系统的改造。所以,client端的侵入性就变的很重要。侵入性越小,越容易部署和测试。CAS框架的优点之一就在于它的client端对应用系统的侵入性比较小。对于Java的Web项目来说,你只需要在web.xml里面添加一个filter,拷贝CAS client的jar包到应用系统,然后改造登陆认证过程即可。如果CAS server用的是Https,那就还需要将证书导入到JVM的可信证书域中,通常是($JAVA_HOME/lib/security/cacerts)。

 

所有的一切看着都挺简单的,但实际部署中你会遇到各式各样的问题。有很多问题网上都有人解答,这里我就记录一下我遇到的一个没找到答案的问题?

现象:

当你配置完CAS server, 也部署了CAS client后。用https登陆CAS server也都没问题时,而你无论如何都无法在登陆后跳转到你期待的页面。尽管一切看起来都配置对了,证书也导了,https也配了,filter也加了。但是还是不停的抛CAS ticket validation expection, CAS server no response错误。

解决方案:

请检查你的client是否把4个filter都配置全了,并且顺序要对。

 <!-- CAS SSO -->
    <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://cas-server:8443/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://client-host:8080</param-value>
        </init-param>
    </filter>

    <filter>
        <filter-name>CAS Validation Filter</filter-name>
        <filter-class>
            org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter
        </filter-class>
        <init-param>
            <param-name>casServerUrlPrefix</param-name>
            <param-value>https://cas-server:8443/cas/</param-value>
        </init-param>
        <init-param>
            <param-name>serverName</param-name>
            <param-value>http://client-host:8080</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 Wrapper Filter</filter-name>
        <filter-class>
            org.jasig.cas.client.util.HttpServletRequestWrapperFilter
        </filter-class>
    </filter>
    <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 Authentication Filter</filter-name>
        <url-pattern>/sso/*</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>CAS Validation Filter</filter-name>
        <url-pattern>/sso/*</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
        <url-pattern>/sso/*</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>CAS Assertion Thread Local Filter</filter-name>
        <url-pattern>/sso/*</url-pattern>
    </filter-mapping>

官方文档特别说明这4个Filter是必须的

The correct order of the filters in web.xml is necessary:

  1. AuthenticationFilter
  2. TicketValidationFilter (whichever one is chosen)
  3. HttpServletRequestWrapperFilter
  4. AssertionThreadLocalFilter

这里我要说明一下为什么这4个filter是必须要配的。

 AuthenticationFilter的作用是用于拦截SSO登陆请求的,当你提交的request符合SSO登陆规则,CAS client会通过这个filter将登陆请求转向到CAS server的登陆界面。因为这是第一步,所以它要在最上面。

TicketValidationFilter的作用是用于拦截登陆返回的跳转请求的。当CAS server确认登陆用户名密码后,会返回一个server ticket,这个ticket会由应用服务器上的CAS client再送回CAS server进行验证,用于防止仿冒攻击的。

HttpServletRequestWrapperFilter的目的是将CAS server返回的信息封装到Http request里面,这样客户端就可以用request.getRemoteUser()来获取用户名等信息了。

AssertionThreadLocalFilter的作用是用于前端程序(通常是前端脚本程序)访问,因为这个时候你无法通过request来获取信息。

所以如果这4个filter不配置正确,就会报各种错误。

posted @ 2012-09-06 17:26  moonz-wu  阅读(7626)  评论(0编辑  收藏  举报