CAS单点登录技术实践

JDK 环境 1.7,操作系统windows,用户权限级别Adminstrator

web服务器:Tomcat 7

生成证书

CAS 通过证书来实现客户端与服务端的信息交互,所以第一步当然是生成证书了

通过JDK自带的工具keytool来生成证书

密码由自己创建,输入完输入的是域名,注意这个域名需要修改,在C:\Windows\System32\drivers\etc\hosts文件添加

127.0.0.1       sso.alingluo.com

将回环地址映射给sso.alingluo.com这个域名,输入其他信息

最后输入Y确认

二,导出证书

密码是刚刚创建的密码,证书导出完成,接下来就可以分发给客户端了

三,为客户端JVM导入证书


将证书添加到JVM的cacerts密钥库中,密码同上

四,应用证书到Tomcat

启用Tomcat的HTTPS加密协议,修改Tomcat目录下conf/server.xml文件并去掉注释,

keystoreFile为key存放路径,keystorePassword是创建证书时创建的密码

   <Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol"
               maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
               clientAuth="false" sslProtocol="TLS"
               keystoreFile="D:/keys/alingluokey" keystorePass="password"/>

五,配置CAS Server

       从官网下载的cas server中会含有一个cas server对应的war包,对应路径为cas-server-3.5.2\modules\cas-server-webapp-3.5.2.war,我们可以把该war包重命名为cas.war,然后丢到tomcat的webapps目录下。

       此外,由于CAS是基于Maven开发的,所以官方建议使用Maven的War覆盖机制。Maven的War覆盖机制是指当一个package类型为war的Maven项目A中引入了一个package类型为war的项目B作为依赖时,最终项目A打包的war包中不仅会包含项目A的内容,还会包含项目B的内容,且相同位置的文件项目A中的会覆盖项目B中的,即当项目A和项目B在WEB-INF下都拥有一个web.xml文件时,最终生成的war包中将使用项目A在WEB-INF下的web.xml文件;而当项目A在WEB-INF下没有web.xml文件,而项目B在WEB-INF下拥有web.xml文件时最终生成的war包中将使用项目B在WEB-INF下的web.xml文件。所以如果我们要修改Cas Server的配置文件,我们可以建立一个自己的基于Maven的Web项目,然后引入Cas Server作为依赖,并在自己的项目中建立对应的deployerConfigContext.xml文件。这有一篇教程:http://elim.iteye.com/blog/2128869

另附上Oracle数据源配置

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
          <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
        <property name="url" value="jdbc.:oracle:thin:@localhost:1521:orcl" />
        <property name="username" value="cas"/>
        <property name="password" value="123456"/>
  </bean>

配置完启动Tomcat服务器,访问https://localhost:8443/cas/login就可以看到登录页面了,输入数据库配置的用户名和密码进行认证

六,配置CAS Client

创建Maven Web项目

pom.xml依赖如下

<dependencies>
    <dependency>
        <groupId>org.jasig.cas.client</groupId>
        <artifactId>cas-client-core</artifactId>
        <version>3.2.1</version>
    </dependency>
    <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.8.2</version>
            <type>jar</type>
        </dependency>
  </dependencies>

编辑web.xml

<!--
        按照顺序配置四个Filter
        1,AuthenticationFilter
        2,TicketValidationFilter
        3,HttpServletRequestWrapperFilter
        4,AssertionThreadLocalFilter
        CAS Client默认会先从init-param取,没取到从context-param取
     -->
     <!--
        AuthenticationFilter用来拦截所有的请求,用以判断用户是否需要通过CAS Server进行认证
        必须指定Cas Server登录地址,casServerLoginUrl
        认证成功后需要跳转地址的serverName或service,参数service具有更高的优先级
        service指定一个确定的URL,serviceName指定的是主机名
      -->
      <context-param>
            <param-name>serverName</param-name>
            <param-value>http://sso.alingluo.com:8080</param-value>
      </context-param>
      
      <!-- 用於单点登出,该过滤器用于实现单点登出功能,可选配置 -->
      <listener>
          <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>
      </listener>
          
      <!--
          该过滤器用于实现单点登出功能,可选配置
       -->
       <filter>
            <filter-name>casSingleSignout</filter-name>
            <filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>
       </filter>
       <filter-mapping>
            <filter-name>casSingleSignout</filter-name>
            <url-pattern>/*</url-pattern>
       </filter-mapping>
       
      <filter>
            <filter-name>casAuthentication</filter-name>
            <filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
            <init-param>
                 <param-name>casServerLoginUrl</param-name>
                 <param-value>https://sso.alingluo.com:8443/cas/login</param-value>
            </init-param>
      </filter>
      <filter-mapping>
            <filter-name>casAuthentication</filter-name>
            <url-pattern>/*</url-pattern>
      </filter-mapping>
      <!--
          在请求通过AuthenticationFilter认证之后,如果请求中携带了参数ticket
          将会由TicketValidationFilter来对携带的ticket进行校验,多种验证ticket的Filter
          都继承自AbstractTciketValidationFilter,使用的TicketValidation不一样
          必须指定的参数,casServerUrlPrefix,用来指定CAS Server对于URL地址的前缀
          serverName或service
       -->
       <filter>
              <filter-name>casTicketValidationFilter</filter-name>
              <filter-class>org.jasig.cas.client.validation.Cas10TicketValidationFilter</filter-class>
              <init-param>
                     <param-name>casServerUrlPrefix</param-name>
                     <param-value>https://sso.alingluo.com:8443/cas</param-value>
              </init-param>
       </filter>
       <filter-mapping>
              <filter-name>casTicketValidationFilter</filter-name>
              <url-pattern>/*</url-pattern>
       </filter-mapping>
       <!--
             HttpServletRequestWrapperFilter用于将每一个请求对应的HttpServletRequest
             封装成内部定义的CasHttpServletRequestWrapper,利用Assertion对象重写getUserPrinicipal()方法
             getRemoteUser()、isUserInRole()方法
        -->
        <filter>
            <filter-name>casHttpServletRequestWrapper</filter-name>
            <filter-class>org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class>
        </filter>
        <filter-mapping>
             <filter-name>casHttpServletRequestWrapper</filter-name>
             <url-pattern>/*</url-pattern>
        </filter-mapping>
        <!--
            AssertionThreadLocalFilter是方便获取Assertion对象,将当前Assertion对象存放到当前的线程变量中
         -->
           
        <filter>
            <filter-name>casAssertionThreadLocalFilter</filter-name>
            <filter-class>org.jasig.cas.client.util.AssertionThreadLocalFilter</filter-class>
        </filter>
        <filter-mapping>
             <filter-name>casAssertionThreadLocalFilter</filter-name>
             <url-pattern>/*</url-pattern>
        </filter-mapping>

到这里就配置完成了,访问客户端项目页面就会跳转到服务端登录页面(https://sso.alingluo.com:8443/cas/login)页面

错误集


TicketValidationFilter下的casServerUrlPrefix配置错误,应为cas Server登录路径的前缀,例如https://sso.alingluo.com:8443/cas

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

证书没有导入到客户端的JVM


CAS Client登录javax.net.ssl.SSLHandshakeException:Received fatal alert:handshake_faile

Jdk1.7无此问题,JDK1.6有此问题

Jvm启动参数中加入-Dhttps.protocols=SSLv3,TLSv1

在Tomcat的catalina.bat中开始行添加set JAVA_OPTS=-Dhttps.protocols=SSLv3,TLSv1

好像Tomcat官方文档不推荐修改catalina.bat文件,但是我懒嫌麻烦,还是修改了吐舌头

参考博文:http://www.iteye.com/blogs/subjects/cas168
                      http://blog.csdn.net/frinder/article/details/7969925

                            感谢他们的无私奉献!


发布了16 篇原创文章 · 获赞 19 · 访问量 7万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章