1. 程式人生 > >單點登入springsecurity+cas

單點登入springsecurity+cas

連結1 基礎  參考價值大

         入門  參考價值很大(sso cas淵源,歷史發展,技術發展,屬於解釋,為什麼這樣設計,等等)

CAS 是通過 TGT(Ticket Granting Ticket) 來獲取 ST(Service Ticket) ,通過 ST 來訪問服務,而 CAS 也有對應 TGT , ST 的實體,而且他們在保護 TGT 的方法上雖然有所區別,但是,最終都可以實現這樣一個目的——免去多次登入的麻煩。

--------------------------------

當 Step3 完成之後, CAS Server 會向 User 傳送一個 Ticket granting cookie (TGC

) 給 User 的瀏覽器,這個 Cookie 就類似 Kerberos(Kerberos  麻省理工學院開發的安全認證系統) 的 TGT ,下次當用戶被 Helloservice2 重定向到 CAS Server 的時候, CAS Server 會主動 Get 到這個 TGC cookie ,然後做下面的事情:
1 如果 User 的持有 TGC 且其還沒失效,那麼就走基礎協議圖的 Step4 ,達到了 SSO 的效果。
2 如果 TGC 失效,那麼使用者還是要重新認證 ( 走基礎協議圖的 Step3) 。

----------------------------

CAS Client 負責部署在客戶端(注意,我是指 Web 應用)目前, CAS Client 支援(某些在完善中)非常多的客戶端,包括 Java、.Net 、ISAPI、Php、Perl、uPortal、 Acegi、Ruby、VBScript 等客戶端,幾乎可以這樣說, CAS 協議能夠適合任何語言編寫的客戶端應用。

---------------------------

CAS 是通過 TGT(Ticket Granting Ticket) 來獲取 ST(Service Ticket)

--------------------------

 SAML 是一種 SSO 標準而 CAS 是一種 SSO 的實現,從 CAS 的 Roadmap 可以看出, CAS 很快會提供對其他 SAML 的支援

------------------------

2.1.1 基礎協議  2.2.2 CAS 的代理模式比較 :模式 1 已經能夠滿足大部分簡單的 SSO 應用,現在,我們探討一種更復雜的情況,即使用者訪問 helloservice , helloservice 又依賴於 helloservice2 來獲取一些資訊.如同:
User à helloservice à helloservice2
這種情況下,假設 helloservice2 也是需要對 User 進行身份驗證才能訪問,那麼,為了不影響使用者體驗(過多的重定向導致 User 的 IE 視窗不停地 閃動 ) , CAS 引入了一種 Proxy 認證機制,即 CAS Client 可以代理使用者去訪問其它 Web 應用。
代理的前提是需要 CAS Client 擁有使用者的身份資訊 ( 類似憑據 )

。 與其說之前我們提到的 TGC 是使用者持有對自己身份資訊的一種憑據,則這裡的 PGT 就是 CAS Client 端持有的對使用者身份資訊的一種憑據。憑藉 TGC , User 可以免去輸入密碼以獲取訪問其它服務的 Service Ticket ,所以,這裡,憑藉 PGT , Web 應用可以代理使用者去實現後端的認證,而無需前端使用者的參與。

備註:

http://www.imooc.com/article/3720 到目前為止,其CAS認證協議已經持續發展了三個版本,v1實現了單點登入,此版本跟Nebula實現的功能差不多。
v2版則重點增加了proxy模式,代理模式是一種更復雜形式的認證,即認證的Web應用(CAS Client)可以作為代理直接訪問需要認證的後端服務(如郵件伺服器),瀏覽器使用者無需再和後端服務直接進行認證互動。這個比較複雜,在門戶中可能會用到,我們這裡不做討論。
v3版本則更加豐富了協議,認證中心驗證票據後不僅可以返回身份ID,還可攜帶使用者暱稱、性別等其他使用者基本資訊。
連結:http://www.blogjava.net/security/archive/2006/10/02/sso_in_action.html

連結 3 部分參考 ,重點看屬於歸納和a依賴b,b依賴c,c需要登入這種情況

CAS 的 SSO 實現方式可簡化理解為: 1 個 Cookie 和 N 個 Session 。 CAS Server 建立 cookie,在所有CAS Client應用認證時使用,各CAS Client應用通過建立各自的 Session 來標識使用者是否已登入。

-------------------------------

Step 3 是使用者認證過程,如果使用者提供了正確的 Credentials , CAS Server 隨機產生一個相當長度、唯一、不可偽造的 Service Ticket ,並快取以待將來驗證,並且重定向使用者到 Service 所在地址(附帶剛才產生的 Service Ticket ) , 併為客戶端瀏覽器設定一個 Ticket Granted Cookie ( TGC )

連結4  部分參考 僅供參考(時序圖見下文中圖),介紹的不錯,簡單易懂

登入狀態判斷 http://www.imooc.com/article/3558
使用者到認證中心登入後,使用者和認證中心之間建立起了會話,我們把這個會話稱為全域性會話。當用戶後續訪問系統應用時,我們不可能每次應用請求都到認證中心去判定是否登入,這樣效率非常低下,這也是單Web應用不需要考慮的。
我們可以在系統應用和使用者瀏覽器之間建立起區域性會話,區域性會話保持了客戶端與該系統應用的登入狀態,區域性會話依附於全域性會話存在,全域性會話消失,區域性會話必須消失。
使用者訪問應用時,首先判斷區域性會話是否存在,如存在,即認為是登入狀態,無需再到認證中心去判斷。如不存在,就重定向到認證中心判斷全域性會話是否存在,如存在,按1提到的方式通知該應用,該應用與客戶端就建立起它們之間區域性會話,下次請求該應用,就不去認證中心驗證了。。

這段話翻譯:
一 
     無session,重定向到CAS Server 然後分兩種情況,
        1, 如果 User 的持有 TGC 且其還沒失效,那麼就走基礎協議圖的 Step4 ,達到了 SSO 的效果。
        2, 如果 TGC 失效,那麼使用者還是要重新認證 ( 走基礎協議圖的 Step3) 。 。  圖中是無TGT 或 TGT 錯誤,我的理解是TGT和TGC類似 可以參考連結2裡內容

   有session,登入狀態。 

---------------------------------------

--寫的不錯
答:在系統A登入成功後,使用者和認證中心之間建立起了全域性會話,這個全域性會話就是TGT(Ticket Granting Ticket),TGT位於CAS伺服器端,TGT並沒有放在Session中,也就是說,CAS全域性會話的實現並沒有直接使用Session機制,而是利用了Cookie自己實現的,這個Cookie叫做TGC(Ticket Granting Cookie),它存放了TGT的id,儲存在使用者瀏覽器上。

為了理解"登入B系統,認證中心是如何判斷使用者已經登入的"裡的提問:


---------------------------時序圖----------------------------------

Auth auth = new Auth(); 
auth.setUserId(verifyResult.getUserId()); 
auth.setUsername(verifyResult.getUsername()); 
auth.setGlobalId(verifyResult.getGlobalId());
 request.getSession().setAttribute("auth", auth); 
//建立本地會話 return "redirect:http://" + returnURL; 

時序圖裡 第一步 判斷是否有session  第六步 建立session ,這兩步裡的session對應這上面一段程式碼( request.getSession().setAttribute("auth", auth);),

這個session裡包含全域性GlobalId。

個人理解總結,僅供自己參考:

這裡面有兩種會話1 使用者和認證中心(client server)之間建立起的全域性會話 2 使用者和 client 客戶端的本地會話。全域性會話和本地會話都包含GlobalId。瀏覽器會儲存兩個cookie/session:和client 客戶端的session ,和client的cookie(TGT)

        Step3是使用者認證過程,如果使用者提供了正確的 Credentials , CAS Server 隨機產生一個相當長度、唯一、不可偽造的 Service Ticket ,並快取以待將來驗證, 併為客戶端瀏覽器設定一個 Ticket Granted Cookie ( TGC),並且重定向使用者到 Service 所在地址(地址指cas client客戶端地址)並附帶剛才產生的 Service Ticket (Ticket  用於cas client客戶端向cas client server驗證使用) 。在系統A登入成功後,使用者和認證中心之間建立起了全域性會話,這個全域性會話就是TGT(Ticket Granting Ticket),TGT位於CAS伺服器端,TGT並沒有放 在Session中,也就是說,CAS全域性會話的實現並沒有直接使用Session機制,而是利用了Cookie自己實現的,這個Cookie叫做TGC(Ticket Granting Cookie),它存放了TGT的id,儲存在使用者瀏覽器上。--這個講的不太好,部分參考吧。

本地會話:在第六步建立。具體建立過程見上文分析。

連結五

這篇圖文詳解部落格裡的TGT和session介紹的更清楚,有點像從零開始仿照sso用自己的程式碼寫/實現sso,學這個可以更深入理解sso。時序圖畫的更容易入門http://www.imooc.com/article/3720

附錄:

單點登入的原理理解了,下一步就是整合springsecurity+cas

這裡介紹下單點登入驗證通過後,授權的問題。假如驗證通過在何處對通過的使用者授權:認證的處理者是CasAuthenticationProvider(

原理見程式碼連結3 http://elim.iteye.com/blog/2270446)

CasAuthenticationProvider首先會利用TicketValidator(Cas概念)對Authentication中包含的ticket資訊進行認證。認證通過後將利用持有的AuthenticationUserDetailsService根據認證通過後回傳的Assertion物件中擁有的username載入使用者對應的UserDetails。AuthenticationUserDetailsService通過userDetailsService從資料庫中根據使用者名稱查出對應的許可權。

Cas Server認證成功後的跳轉地址,這裡要跳轉到我們的Spring Security應用,之後會由CasAuthenticationFilter處理,預設處理地址為/j_spring_cas_security_check 

Spring Security應用整合Cas使用Cas Proxy作為被代理端(意味著也可以作代理端)時主要需要進行三點修改...

(http://www.cnblogs.com/vhua/p/cas_5.html CAS 基本流程圖(沒有使用PROXY代理),使用代理的 CAS 流程圖。
http://elim.iteye.com/blog/2270446 整合Cas。裡面有使用代理模式。)

<bean id="casAuthenticationProvider"
   class="org.springframework.security.cas.authentication.CasAuthenticationProvider">
      <!-- 通過username來載入UserDetails -->
      <property name="authenticationUserDetailsService">
         <bean class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
            <!-- 真正載入UserDetails的UserDetailsService實現 -->
            <constructor-arg ref="userDetailsService" />
         </bean>
      </property>
      <property name="serviceProperties" ref="serviceProperties" />
      <!-- 配置TicketValidator在登入認證成功後驗證ticket -->
      <property name="ticketValidator">
         <bean class="org.jasig.cas.client.validation.Cas20ProxyTicketValidator">
            <!-- Cas Server訪問地址的字首,即根路徑-->
            <constructor-arg index="0" value="https://elim:8443/cas" />
            <!-- 指定Cas Server回撥傳遞pgtId和pgtIou的地址,該地址必須使用https協議 -->
            <property name="proxyCallbackUrl" value="https://elim:8043/app/proxyCallback"/>
            <property name="proxyGrantingTicketStorage" ref="proxyGrantingTicketStorage"/>
            <!-- 作為被代理端時配置接收任何代理 -->
            <property name="acceptAnyProxy" value="true"/>
         </bean>
      </property>
      <property name="key" value="key4CasAuthenticationProvider" />
   </bean>


   <bean id="userDetailsService"
      class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
      <property name="dataSource" ref="dataSource" />
   </bean>

我們關心的是CasAuthenticationFilter-->AuthenticationManager-->CasAuthenticationProvider--authenticationUserDetailsService-->UserDetailsByNameServiceWrapper-->userDetailsService-->JdbcDaoImpl流程。JdbcDaoImpl也可以用自定義的實現類代替。

這裡以CasAuthenticationProvider的authenticateNow方法作為入口跟蹤(圖片看不清可另存為檢視)


Spring Security(20)——整合Cas:http://elim.iteye.com/blog/2270446  --haohaoxuexi

http://www.cnblogs.com/vhua/p/cas_5.html CAS 基本流程圖(沒有使用PROXY代理),使用代理的 CAS 流程圖。
http://elim.iteye.com/blog/2270446 整合Cas。裡面有使用代理模式。

http://elim.iteye.com/blog/2145751

cas server:http://www.iteye.com/blogs/subjects/cas168

cas server

cas 服務端的一些連結  
Cas的客戶端(cas+springsecurity)和服務端結合的程式碼都有--(偏程式碼必看,可以此為藍本搭建專案)  
https://github.com/freehuoshan  
cas server 配置介紹,偏理論介紹   
http://www.iteye.com/blogs/subjects/cas168  
cas 客戶端和服務端原始碼解析 偏原始碼  
http://blog.csdn.net/dovejing/article/category/3013985  

https://github.com/freehuoshan/authority --整合 CAS 單點登入,單點登入與許可權控制外掛化
https://github.com/sgq0085/learn --learn-cas-clientlearn-cas-server Shiro通過Redis管理會話實現叢集

https://github.com/ameizi/cas-server-webapp

http://www.cnblogs.com/leefreeman/archive/2012/11/13/2767644.html --CAS擴充套件——自定義查詢資料庫驗證Handler

http://www.cnblogs.com/leefreeman/archive/2012/12/05/2802556.html --CAS擴充套件——自定義加密演算法

http://sgq0085.iteye.com/blog/2099196 --cas server 4.0深度研究

原始碼解析結合第一個連結看,入口在login-webflow.xml,原始碼解析裡從var name="credentials", 開始,對應著第一個連結的var name="credential"  

###springsecurity+cas程式碼可以部分借鑑:點選開啟連結  問題:去獲取訪問當前資源url需要哪些許可權role_xx。容器啟動時會操作一次,如果後來管理員重新授權,訪問當前url對應的需要的許可權變了怎麼辦。即系統會在初始化時一次將所有資源載入到記憶體中,即使在資料庫中修改了資源資訊,系統也不會再次去從資料庫中讀取資源資訊。這就造成了每次修改完資料庫後,都需要重啟系統才能時資源配置生效。我們只要想辦法在管理員修改資料後,更新記憶體中資料map即可。參見我上一篇部落格:http://mp.csdn.net/postedit/52203032