天天看點

CAS技術原理及分析

CAS實作原理:

CAS技術原理及分析

認證流程分析:

1:使用者第一次通路受保護的應用。受保護的應用通過其中配置的統一認證過濾器隊請求進行過濾,未發現在session中有特定的使用者資訊,也未發現有ST參數。

2:應用系統将認定使用者第一次進入受保護的系統中,重定向到統一認證系統中特定的路徑。通常該路徑為 http:// 統一認證IP:端口/casserver/login

3:統一認證系統判斷使用者在統一認證系統中是否登入過。

4:如果沒有登入過,則将使用者定向到登入界面。

5:使用者在登入界面輸入使用者名和密碼等資訊,并進行送出。

6:統一認證系統驗證使用者送出的憑證是否正确,如果正确,生成cookie形式的TGT(ticket grant ticket)和一個ST(service ticket)。并通過重定向跳回到受保護的系統中。并且,将ST作為參數附加在URL後面。

7:進入受保護系統中,請求經由統一認證過濾器進行過濾,發現雖然在session中不存在特定的使用者資訊,但是存在ST票據。

8:有統一認證用戶端持有ST票據通過http請求,發送到統一認證端進行認證票據的有效性。

9:統一認證系統認證票據有效,相應使用者資訊到受保護系統。

10:受保護系統獲得使用者資訊,在session中設定特定的使用者資訊。傳回使用者通路資源。

了解了CAS實作單點登入的原理之後,我們就來看一下CAS伺服器端的整體結構:

分析web工程一般都是從web.xml檔案開始進行分析的。我們就先來看一下web.xml

首先是spring進行控制反轉控制的配置檔案。通常使用過spring的開發人員應該對spring會比較了解,這裡先不解釋,以後的分析中,會對spring的兩大特性IOC和AOP進行相應的分析。

    <context-param>

       <param-name>contextConfigLocation</param-name>

       <param-value>

           /WEB-INF/spring-configuration/*.xml

           /WEB-INF/deployerConfigContext.xml

       </param-value>

    </context-param>

第二部分是CAS的日志檔案的配置。這個方面以後将會作為一個知識點進行相對系統的分析。

    <context-param>

       <param-name>log4jConfigLocation</param-name>

       <param-value>classpath:log4j.xml</param-value>

    </context-param>

    <context-param>

       <param-name>log4jExposeWebAppRoot</param-name>

       <param-value>false</param-value>

    </context-param>

  <context-param>

    <param-name>log4jRefreshInterval</param-name>

    <param-value>60000</param-value>

  </context-param>

下面是CAS自身業務相關的重點了。

    <filter>

       <filter-name>CAS Client Info Logging Filter</filter-name>

        <filter-class>com.github.inspektr.common.web.ClientInfoThreadLocalFilter</filter-class>

    </filter>

該filter主要是對進入CAS自身的接入系統管理的請求進行過濾的。該過濾主要是采用springsecurity架構來處理的。這會在将來也會作為一個知識點進行重點分析。

    <filter>

        <filter-name>springSecurityFilterChain</filter-name>

        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>

    </filter>

該過濾器是對請求的字元編碼就行處理的過濾器。相信大家都會很熟悉。

    <filter>

        <filter-name>characterEncodingFilter</filter-name>

        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>

    </filter>

    <filter-mapping>

        <filter-name>characterEncodingFilter</filter-name>

        <url-pattern>/*</url-pattern>

    </filter-mapping>

    <filter-mapping>

      <filter-name>springSecurityFilterChain</filter-name>

      <url-pattern>/services/*</url-pattern>

    </filter-mapping>

    <filter-mapping>

       <filter-name>CAS Client Info Logging Filter</filter-name>

       <url-pattern>/*</url-pattern>

    </filter-mapping>

這裡是對日志初始化相關的監聽器。将會在日志部分重點分析。(其實不光是有日志,還有性能分析。)

    <listener>

       <listener-class>

           org.springframework.web.util.Log4jConfigListener

       </listener-class>

    </listener>

    <listener>

       <listener-class>

           org.jasig.cas.web.init.SafeContextLoaderListener

       </listener-class>

    </listener>

這裡是CAS進行統一認證的重點部分。和認證相關的請求都是由這個servlet進行處理的。

    <servlet>

       <servlet-name>cas</servlet-name>

       <servlet-class>

           org.jasig.cas.web.init.SafeDispatcherServlet

       </servlet-class>

       <init-param>

           <param-name>publishContext</param-name>

           <param-value>false</param-value>

       </init-param>

       <load-on-startup>1</load-on-startup>

    </servlet>

    <servlet-mapping>

       <servlet-name>cas</servlet-name>

       <url-pattern>/login</url-pattern>

    </servlet-mapping>

    <servlet-mapping>

       <servlet-name>cas</servlet-name>

       <url-pattern>/logout</url-pattern>

    </servlet-mapping>

    <servlet-mapping>

       <servlet-name>cas</servlet-name>

       <url-pattern>/validate</url-pattern>

    </servlet-mapping>

    <servlet-mapping>

       <servlet-name>cas</servlet-name>

       <url-pattern>/serviceValidate</url-pattern>

    </servlet-mapping>

    <servlet-mapping>

       <servlet-name>cas</servlet-name>

       <url-pattern>/samlValidate</url-pattern>

    </servlet-mapping>

    <servlet-mapping>

       <servlet-name>cas</servlet-name>

       <url-pattern>/proxy</url-pattern>

    </servlet-mapping>

    <servlet-mapping>

       <servlet-name>cas</servlet-name>

       <url-pattern>/proxyValidate</url-pattern>

    </servlet-mapping>

    <servlet-mapping>

       <servlet-name>cas</servlet-name>

       <url-pattern>/CentralAuthenticationService</url-pattern>

    </servlet-mapping>

    <servlet-mapping>

       <servlet-name>cas</servlet-name>

       <url-pattern>/services/add.html</url-pattern>

    </servlet-mapping>

    <servlet-mapping>

        <servlet-name>cas</servlet-name>

        <url-pattern>/services/viewStatistics.html</url-pattern>

    </servlet-mapping>

    <servlet-mapping>

       <servlet-name>cas</servlet-name>

       <url-pattern>/services/logout.html</url-pattern>

    </servlet-mapping>

    <servlet-mapping>

       <servlet-name>cas</servlet-name>

       <url-pattern>/services/loggedOut.html</url-pattern>

    </servlet-mapping>

    <servlet-mapping>

       <servlet-name>cas</servlet-name>

       <url-pattern>/services/manage.html</url-pattern>

    </servlet-mapping>

    <servlet-mapping>

       <servlet-name>cas</servlet-name>

       <url-pattern>/services/edit.html</url-pattern>

    </servlet-mapping>

    <servlet-mapping>

       <servlet-name>cas</servlet-name>

       <url-pattern>/openid/*</url-pattern>

    </servlet-mapping>

    <servlet-mapping>

       <servlet-name>cas</servlet-name>

       <url-pattern>/services/deleteRegisteredService.html</url-pattern>

    </servlet-mapping>

    <servlet-mapping>

        <servlet-name>cas</servlet-name>

        <url-pattern>/authorizationFailure.html</url-pattern>

    </servlet-mapping>

    <servlet-mapping>

        <servlet-name>cas</servlet-name>

        <url-pattern>/403.html</url-pattern>

    </servlet-mapping>

    <session-config>

       <!-- Default to 5minute session timeouts -->

       <session-timeout>5</session-timeout>

    </session-config>

    <error-page>

        <exception-type>org.springframework.context.ApplicationContextException</exception-type>

       <location>/WEB-INF/view/jsp/brokenContext.jsp</location>

    </error-page>

注意:一個filter和一個servlet是可以對多個路徑進行過濾的。是以,遇到一個servlet處理多個路徑的時候,最好不要嘗試攔截所有請求路徑,然後在servlet和filter中進行區分處理,這樣效率是會很低的。可以多些幾個filtermapping,多些幾個servletmapping。雖然讓web.xml看上去複雜很多,但效率會高出很多。