1. 程式人生 > >CAS認證流程

CAS認證流程

一 配置例項

應用場景: cas 服務部署在192.168.7.115 ,是一個web 應用,訪問地址為:https://cas.mycompany.com:8443/cas/ 。web1 應用位於192.168.7.90 ,訪問地址為:http://192.168.7.90:8081/web1 ,web2 應用位於192.168.7.90 ,訪問地址為:http://192.168.7.90:8082/web2 。web1 和web2 通過cas 服務實現SSO 功能。瀏覽器位於本地localhost 。

cas 伺服器: 172.16.52.35 啟動8443 埠,需配置證書

web1 : 172.16.52.35

   hosts 配置: 172.16.52.35  cas.mycompany.com

    web.xml 裡的配置:

    <context-param>

        <param-name>casServerUrlPrefix</param-name>

        <param-value>https://cas.mycompany.com:8443/cas/</param-value>

    </context-param>

    <context-param>

        <param-name>serverName</param-name>

        <param-value>172.16.52.35:8081</param-value>

    </context-param>

    <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.mycompany.com:8443/cas/login</param-value>

        </init-param>

    </filter>

    <filter>

        <filter-name>CAS Validation Filter</filter-name>

        <filter-class>

org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter

</filter-class>

    </filter>

    <filter-mapping>

        <filter-name>CAS Authentication Filter</filter-name>

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

    </filter-mapping>

    <filter-mapping>

        <filter-name>CAS Validation Filter</filter-name>

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

    </filter-mapping>

    JDK 啟動引數需加上( 驗證CAS 伺服器證書的需要) :

      -Djavax.net.ssl.trustStore=/home/yz/web1/conf/cas-client-trust-cert.jks

   [email protected]#

web2 : 172.16.52.35

   hosts 配置: 172.16.52.35  cas.mycompany.com

   web.xml 裡的配置:

    同web1 裡web.xml 的配置,只是serverName 屬性的值變成了192.168.7.90:8082

JDK 啟動引數需加上( 驗證CAS 伺服器證書的需要) :

      -Djavax.net.ssl.trustStore=/home/yz/web2/conf/cas-client-trust-cert.jks

   [email protected]#

注:

1 casServerLoginUrl 引數的值是cas 伺服器login 介面的值。web 應用裡的cas client 在認證的時候會redirect到 cas 伺服器,redirect 的url 就是casServerLoginUrl ,因為是redirect ,所以瀏覽器所在機器要配置cas 伺服器的域名。

2 casServerUrlPrefix 引數的值是cas 服務的訪問地址。cas client 驗證ticket 的時候,要訪問cas 服務的/serviceValidate 介面,使用的url 就是${ casServerUrlPrefix }serviceValidate ,因為客戶web 應用要驗證cas的證書,所以證書cn 欄位的值必須和casServerUrlPrefix 裡設定的cas 伺服器的域名保持一致,並且在web 應用的伺服器上配置cas 服務的訪問域名。

2 serverName 引數,cas client 會用來生成service 引數,並且cas 伺服器在認證通過、ticket 驗證通過後,會redirect 到web 應用,redirect 的url 就是service 引數的值。serverName 引數可以是IP ,也可以是域名,只要保證瀏覽器能訪問到即可。

二 CAS 簡單介紹

CAS 的主要文件:

  

CAS 官方網站上的介紹圖

主要原理:使用者第一次訪問一個CAS 服務的客戶web 應用時(訪問URL :http://192.168.7.90:8081/web1 ),部署在客戶web 應用的cas AuthenticationFilter ,會截獲此請求,生成service 引數,然後redirect 到CAS 服務的login 介面,url 為https://cas:8443/cas/login?service=http%3A%2F%2F192.168.7.90%3A8081%2Fweb1%2F,認證成功後,CAS 伺服器會生成認證cookie ,寫入瀏覽器,同時將cookie 快取到伺服器本地,CAS 伺服器還會根據service 引數生成ticket,ticket 會儲存到伺服器,也會加在url 後面,然後將請求redirect 回客戶web 應用,url為http://192.168.7.90:8081/web1/?ticket=ST-5-Sx6eyvj7cPPCfn0pMZuMwnbMvxpCBcNAIi6-20 。這時客戶端的AuthenticationFilter 看到ticket 引數後,會跳過,由其後面的TicketValidationFilter 處理,TicketValidationFilter會利用httpclient 工具訪問cas 服務的/serviceValidate 介面, 將ticket 、service 都傳到此介面,由此介面驗證ticket的有效性,TicketValidationFilter 如果得到驗證成功的訊息,就會把使用者資訊寫入web 應用的session 裡。至此為止,SSO 會話就建立起來了,以後使用者在同一瀏覽器裡訪問此web 應用時,AuthenticationFilter 會在session 裡讀取到使用者資訊,所以就不會去CAS 認證,如果在此瀏覽器裡訪問別的web 應用時,AuthenticationFilter在session 裡讀取不到使用者資訊,會去CAS 的login 介面認證,但這時CAS 會讀取到瀏覽器傳來的cookie ,所以CAS 不會要求使用者去登入頁面登入,只是會根據service 引數生成一個ticket ,然後再和web 應用做一個驗證ticket 的互動而已。

二 CAS 客戶端 Filter 的處理邏輯

1 AuthenticationFilter

  if(url 中無ticket 引數 && session 中沒有TicketValidationFilter 置的assertion 物件){

     response.sendRedirect(cas 伺服器的/login 介面);// 生成service 引數,新增到url 後面

  }

  else{

    不做處理

  }

2 TicketValidationFilter

  if(url 中有ticket 引數){

     通過httpclient 工具訪問cas 伺服器的/serviceValidate 介面驗證ticket 的有效性,驗證失敗,顯示錯誤頁面,驗證成功,則生成標識使用者身份的assertion 物件,放入session 。

  }

  else{

    不做處理

  }

注:

1 AuthenticationFilter 在前,TicketValidationFilter 在後。

2 AuthenticationFilter :

   1 )url 中無ticket 引數,且session 中沒有TicketValidationFilter 置的assertion 物件,這種情況說明使用者還沒有認證,AuthenticationFilter 會去做認證處理;

   2 )url 中無ticket 引數,且session 中有TicketValidationFilter 置的assertion 物件,這種情況說明使用者已經認證成功,AuthenticationFilter 不做處理;

   3 )url 中有ticket 引數,這種情況說明使用者已經認證成功,但還需要經TicketValidationFilter 去驗證ticket,AuthenticationFilter 不做處理。

3 TicketValidationFilter :只有客戶端呼叫cas 伺服器的/login 介面, 併成功認證,redirect 回客戶端時,url 裡才帶有ticket 引數,在這種情況下,TicketValidationFilter 才做處理。

三 CAS 服務端的處理邏輯

    CAS 服務端總共對外暴露了7 個介面,客戶端通過訪問這7 個介面與服務端互動,這7 個介面為:/login、/logout 、/validate 、/serviceValidate 、/proxy 、/proxyValidate 、/CentralAuthenticationService 。/login 是認證介面,/logout 是退出介面,負責銷燬認證cookie,/validate 、/serviceValidate 是驗證ticket 用的介面,其中/validate 是CAS1.0 定義的,/serviceValidate 是CAS2.0 定義的,其中/serviceValidate 返回xml 格式的資料,/proxy 、/proxyValidate 是支援代理認證功能的介面,/CentralAuthenticationService 介面用於和遠端的web services 互動。對於一般web 應用的單點登入來講,/login 、/logout 、/serviceValidate 這3 個介面已經可以滿足要求 。CAS 協議中已經對這些介面做了定義,連結為:http://www.jasig.org/cas/protocol 。下面是我對CAS 各個介面實現的的詳細說明。

/login:

登入流程這部分要考慮到不同種類使用者憑證的獲取方案,以及客戶應用傳來的service 、gateway 、renew 引數的不同取值組合,CAS 為了實現流程的高度可配置性,採用了Spring Web Flow 技術。通過閱讀CAS 釋出包裡的login-webflow.xml 、cas-servlet.xml 、applicationContext.xml 這3 個檔案,我找出 了登入有關的所有元件,並畫出了它的處理流程圖。

                                                              CAS 預設的登入處理流程

        第一次訪問Web 應用的流程走向

               已經登入web1 後,訪問web1 的資源(web1 沒有啟動session ),或訪問web2 的資源

注:

1 : InitialFlowSetupAction: 是流程的入口。用 request.getContextPath() 的值來設定 cookie 的 Path 值, Cookie的 path 值是在配置檔案裡定義的,但這個 Action 負責將 request.getContextPath() 的值設定為 Cookie 的 path值,這是在 cas 部署環境改變的情況下,靈活地設定 cookie path 的方式;把 cookie 的值以及 service 引數的值放入 requestContext 的 flowscope 裡。

2 : GenerateServiceTicketAction 此 Action 負責根據 service 、 GTC cookie 值生成 ServiceTicket 物件,ServiceTicket 的 ID 就是返回給客戶應用的 ticket 引數,如果成功建立 ServiceTicket ,則轉發到 WarnAction ,如果建立失敗,且 gateway 引數為 true ,則直接 redirect 到客戶應用, 否則則需要重新認證。

3 : viewLoginForm 這是登入頁面, CAS 在此收集使用者憑證。 CAS 提供的預設實現是 /WEB-INF/view/jsp/simple/ui/casLoginView.jsp 。

4 : bindAndValidate 對應 AuthenticationViaFormAction 的 doBind 方法,該方法負責蒐集登入頁面上使用者錄入的憑證資訊(使用者名稱、密碼等),然後把這些資訊封裝到 CAS 內部的 Credentials 物件中。使用者在casLoginView.jsp 頁面上點選提交後,會觸發此方法。

5:submit   對應 AuthenticationViaFormAction 的 submit 方法 , 如果 doBind 方法成功執行完, 則觸發 submit 方法,此方法負責呼叫 centralAuthenticationService 的      grantServiceTicket 方法,完成認證工作,如果認證成功,則生成 TicketGrantingTicket 物件,放在快取裡, TicketGrantingTicket 的 ID 就是 TGC Cookie 的 value值。

6 : warn  CAS 提供了一個功能:使用者在一個 web 應用中跳到另一個 web 應用時, CAS 可以跳轉到一個提示頁面,該頁面提示使用者要離開一個應用進入另一個應用,可以讓使用者自己選擇。使用者在登入頁面 viewLoginForm 上選中了 id=”warn” 的複選框,才能開啟這個功能。

WarnAction 就檢查使用者有沒有開啟這個功能,如果開啟了,則轉發到showWarnView, 如果沒開啟,則直接redirect 到客戶應用。

7 :SendTicketGrantingTicketAction 此Action 負責為response 生成TGC Cookie ,cookie 的值就是AuthenticationViaFormAction 的 submit 方法生成的 TicketGrantingTicket 物件的 ID 。

8 : viewGenerateLoginSuccess 這是 CAS 的認證成功頁面。

/logout: ( 對應實現類 org.jasig.cas.web.LogoutController )

   處理邏輯:   

        1) removeCookie

       2) 在服務端刪除TicketGrantingTicket 物件(此物件封裝了cookie 的value 值)

       3 )redirect 到退出頁面,有2 種選擇:

          if(LogoutController 的followServiceRedirects 屬性為true 值,且url 裡的service 引數非空){

                redirect 到 sevice 引數標識的url

             }

          else{

             redirect 到內建的casLogoutView (cas/WEB-INF/view/jsp/default/ui/casLogoutView.jsp ),如果url 裡有url 引數,則此url 引數標識的連結會顯示在casLogoutView 頁面上。

           }

/serviceValidate: (對應實現類 org.jasig.cas.web.ServiceValidateController )

     處理邏輯:  

  如果service 引數為空或ticket 引數為空,則轉發到failureView (/WEB-INF/view/jsp/default/protocol/2.0/casServiceValidationFailure.jsp )

    驗證ticket 。以ticket 為引數,去快取裡找ServiceTicketImpl 物件,如果能找到,且沒有過期,且ServiceTicketImpl 物件對應的service 屬性和service 引數對應,則驗證通過,驗證通過後,請求轉發至casServiceSuccessView (cas/WEB-INF/view/jsp/default/protocol/2.0/casServiceValidationSuccess.jsp ),驗證不通過,則轉發到failureView 。

四 認證相關的概念及流程

概念

  • Credentials 使用者提供的用於登入用的憑據資訊,如使用者名稱/ 密碼、證書、IP 地址、Cookie 值等。比如 UsernamePasswordCredentials ,封裝的是使用者名稱和密碼。CAS 進行認證的第一步,就是把從UI 或request 物件裡取到的使用者憑據封裝成Credentials 物件,然後交給認證管理器去認證。

  • AuthenticationHandler 認證Handler, 每種AuthenticationHandler 只能處理一種Credentials ,如AbstractUsernamePasswordAuthenticationHandler 只負責處理 U sernamePasswordCredentials 。

  • Principal 封裝使用者標識,比如 SimplePrincipal, 只是封裝了使用者名稱。認證成功後,credentialsToPrincipalResolvers 負責由 Credentials 生成 Principal 物件。

  • CredentialsToPrincipalResolvers 負責由 Credentials 生成 Principal 物件,每種CredentialsToPrincipalResolvers 只處理 一種Credentials ,比如UsernamePasswordCredentialsToPrincipalResolver 負責從 U sernamePasswordCredentials 中取出使用者名稱,然後將其賦給生成的 SimplePrincipal 的 ID 屬性。

  • AuthenticationMetaDataPopulators 負責將 Credentials 的一些屬性賦值給 Authentication 的 attributes屬性。

  • Authentication   Authentication是認證管理器的最終處理結果, Authentication 封裝了 Principal ,認證時間,及其他一些屬性(可能來自 Credentials )。

  • AuthenticationManager 認證管理器得到 Credentials 物件後,負責排程AuthenticationHandler 去完成認證工作,最後返回的結果是 Authentication 物件。

  • CentralAuthenticationService  CAS 的服務類,對 Web 層提供了一些方法。該類還負責呼叫AuthenticationManager 完成認證邏輯

序列圖

CAS 認證處理序列圖

類圖

CAS 認證類圖

--------------------- 本文來自 dongdong_java 的CSDN 部落格 ,全文地址請點選:https://blog.csdn.net/dongdong_java/article/details/22293377?utm_source=copy