cas单点登录环境搭建

公司最近想做一个类似单点登录功能的项目,考虑用cas还是用memcache达到单点登录功能。自己以前搭过cas+shiro的环境,记忆已有些模糊。重新搭一下cas的环境,遇到了一些问题,写下来,希望能帮到某些人,也留着以后忘记的时候,拿来看看。以下是一些步骤,网上也有很多类似的文章,都大同小异:

一  环境准备

      在本机安装jdk(安装方法网上很多,如:http://www.blogjava.net/jackyfoo/archive/2007/01/20/95034.html),搭建tomcat(本人6.0以上)环境。从cas官网下载cas服务端(下载地址:http://downloads.jasig.org/cas/cas-server-3.5.2-release.zip)


二 设置证书

    在cas服务端的机器上,通过jdk自带的keytool生成证书,如下:

  keytool -genkey -alias caskey -keyalg RSA -keystore d:\keys\caskey.keystore (其中caskey为别名,把证书caskey.keystore保存到d:\keys目录下)

  

(注意,图的文件命名跟上面给出的文件名字不一样)

  导出证书

  keytool -export -trustcacerts -file d:\keys\caskey.crt -alias caskey-keystore d:\keys\caskey.keystore (导出证书caskey.crtd:\keys\目录下


  (注意,图的文件命名跟上面给出的文件名字不一样)

导入证书到cas客户端(本人服务端和客户端都在一台机器上,首先命令窗口要到jre的指定目录下,本机为:C:\Program Files\Java\jdk1.6.0_20\jre\lib\security),如:

   keytool -import -trustcacerts -keystore cacerts -file d:\keys\caskey.crt -alias caskey-storepass changeit (其中changeit这个密码为固定,不能改)


(注意,图的文件命名跟上面给出的文件名字不一样)


三、开启服务端Tomcat的SSL连接服务(注意:确保Tomcat所用的JDK和之前所导入证书的JDK是相同的,有的eclipse中的tomcat是用的eclipse自带的jdk的,这个要区分好的,因为本人刚开始跑应用的时候用的是eclipse的jetty插件,用的jdk不是本机的jdk,当回调的时候抛出java.security.cert.CertificateException: No name matching www.casserver.com found异常,www.casserver.com为本人cas服务端的域名

修改Tomcat的conf下面server.xml文件,去掉以下代码的注释,然后添加你自己的keystore

<Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol" SSLEnabled="true"
               maxThreads="150" scheme="https" secure="true"
               clientAuth="false" sslProtocol="TLS" 
keystoreFile="d:\keys\caskey.keystore" keystorePass="123456"/> (caskey.keystore为生成的证书,123456为证书密码)

四、部署cas服务端

        解压cas-server-3.5.2-release.zip,复制modules下面的cas-server-webapp-3.5.2.war到tomcat的webapp下面,重命名为cas.war,启动tomcat后,用浏览器访问https://你的域名:8443/cas就可以访问。默认的情况下,输入相同的用户名和密码就可以成功登录。这种需要通常都不适合用户需求,可以修改cas项目的deployerConfigContext.xml配置文件。在<sec:user-service id="userDetailsService">这个节点后面添加casDataSource:


注释掉SimpleTestUsernamePasswordAuthenticationHandler,添加QueryDatabaseAuthenticationHandler:



同时,还要把需要的jar包丢进tomcat的cas项目的lib目录下,否则,会抛出某些类找不到的异常。这些包分别是:mysql-connector-java-5.1.15.jar(这是mysql的驱动包),commons-dbcp-1.4.jar,commons-pool-1.6.jar(这两个是配置数据源依赖的包),cas-server-support-jdbc-3.5.2.jar(QueryDatabaseAuthenticationHandler就在这个包里面,默认是没有的,可以到cas-server-3.5.2-release.zip解压后modules目录下拷贝。


五、配置客户端(即应用系统)

本人的项目用的是maven管理,只要把依赖加进去就可以,依赖如下:

<dependency>
<groupId>org.jasig.cas.client</groupId>
<artifactId>cas-client-core</artifactId>
<version>3.2.1</version>
</dependency>

在应用系统有web.xml做以下配置:

<!-- 该过滤器用于实现单点登出功能,可选配置。 -->  
    <filter>  
        <filter-name>CAS Single Sign Out Filter</filter-name>  
        <filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>  
    </filter>  
    <filter-mapping>  
        <filter-name>CAS Single Sign Out Filter</filter-name>  
        <url-pattern>/*</url-pattern>  
    </filter-mapping>  
  
    <!-- 该过滤器负责用户的认证工作,必须启用它 -->  
    <filter>  
        <filter-name>CASFilter</filter-name>  
        <filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>  
        <init-param>  
            <param-name>casServerLoginUrl</param-name>  
            <param-value>https://www.casserver.com:8443/cas/login</param-value>  <!--  这里是我的cas服务端的登录访问地址-->
        </init-param>  
        <init-param>  
            <param-name>serverName</param-name>  
            <param-value>http://www.casclient1.com:8085</param-value>  <!--这里是我的应用地址,即回调地址-->
        </init-param>  
    </filter>  
    <filter-mapping>  
        <filter-name>CASFilter</filter-name>  
        <url-pattern>/*</url-pattern>  
    </filter-mapping>  
  
    <!-- 该过滤器负责对Ticket的校验工作,必须启用它 -->  
    <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://www.casserver.com:8443/cas</param-value>  <!--  这里是我的cas服务端的访问地址-->
        </init-param>  
        <init-param>  
            <param-name>serverName</param-name>  
            <param-value>http://www.casclient1.com:8085</param-value>  <!--这里是我的应用地址,即回调地址-->
        </init-param>  
    </filter>  
    <filter-mapping>  
        <filter-name>CAS Validation Filter</filter-name>  
        <url-pattern>/*</url-pattern>  
    </filter-mapping>  
  
    <!-- 该过滤器负责实现HttpServletRequest请求的包裹, 比如允许开发者通过HttpServletRequest的getRemoteUser()方法获得SSO登录用户的登录名,可选配置。 -->  
    <filter>  
        <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>  
        <filter-class>  
            org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class>  
    </filter>  
    <filter-mapping>  
        <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>  
        <url-pattern>/*</url-pattern>  
    </filter-mapping>  
  
    <!-- 该过滤器使得开发者可以通过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 Assertion Thread Local Filter</filter-name>  
        <url-pattern>/*</url-pattern>  
    </filter-mapping>  

以上的配置网络上很容易找到。同时,可以修改系统的hosts文件(C:\WINDOWS\system32\drivers\etc\hosts),设置域名,我的hosts文件如下:


到这里,cas单点登录基本部署完成了。用户可以访问,www.casclient1.com,当未登录的时候,会跳转到www.casserver.com(cas服务端)进行登录认证,认证通过后,回调到www.casclient1.com上。

本人理解的单点登录流程大概如下:

首先用户访问应用,应用配置了cas的filter,filter拦截,根据web.xml的配置地址,然后定向到cas服务端上,cas服务端检查用户的cookie,发现用户没曾登录,就显示登录页面让用户登录认证。认证通过后,cas往用户的客户端写加密的cookie,然后回调到用户实际访问的应用地址。如果发现用户已经登录,就直接回调到用户实际访问的应用地址,而无需用户再登录。无论用户是否登录过,都要经过cas服务端,再进行回调。

       以上cas的配置方式跟网上的大同小异,不过加入了本人遇到的一些问题,希望能帮遇到同样问题的人更好理解。也因本人知识有限,如有不对,希望指正。


补充:

通常我们添加用户的时候,密码都是通过加密了的,这样,对登录的输入密码也要加密,才能和数据库的密码进行匹配。看了一下QueryDatabaseAuthenticationHandler(在cas-server-support-jdbc.jar包下)的原码,在对密码的匹配时,调用了getPasswordEncoder()方法来对输入密码进行加密。源码如下:


显然getPasswordEncoder()方法是在父类定义的,通过跟代码,可以看到在cas-server-core.jar包下的AbstractUsernamePasswordAuthenticationHandler类中定义,代码如下:


该类中默认使用了PlainTextPasswordEncoder类来进行加密,但PlainTextPasswordEncoder这个类的是对密码没有任何加密动作,直接返回密码的,代码如下:


所有,只要自己写一个Encoder,替换PlainTextPasswordEncoder,就能达到自己加密方法的效果。自己的Encoder代码如下:


其中,用的是commons-codec.jar包下的DigestUtils进行加密。当然,加密方法必须和保存到数据库的密码加密方法一致。


然后,修改cas项目的deployerConfigContext.xml配置文件。添加自己的Encoder:

<bean id="passwordEncode" class="com.cas.encode.passwordencode.MD5Encoder"/> 

把encoder注入到QueryDatabaseAuthenticationHandler中

<bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">  
<property name="dataSource" ref="casDataSource" />  
<property name="sql" value="select password from user where username = ?" /> 
<property name="passwordEncoder" ref="passwordEncode" /> 
</bean>

这样,加密方式就起作用。

2013.7.31

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值