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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章