簡單的 SSO 的體系中,會有下面三種角色:前端
1 , User (多個)web
2 , Web 應用(多個)數據庫
3 , SSO 認證中心( 1 個)後端
雖然 SSO 實現模式千奇百怪,但萬變不離其宗:跨域
1 Web 應用不處理 User 的登陸,不然就是多點登錄了,全部的登陸都在 SSO 認證中心進行。瀏覽器
2 SSO 認證中心經過一些方法來告訴 Web 應用當前訪問用戶到底是不是張三 / 李四。緩存
3 SSO 認證中心和全部的 Web 應用創建一種信任關係, SSO 認證中心對用戶身份正確性的判斷會經過某種方法告之 Web 應用,並且判斷結果必須被 Web 應用信任。安全
CAS ( Central Authentication Service ) 是 Yale 大學發起的一個企業級的、開源的項目,旨在爲 Web 應用系統提供一種可靠的單點登陸解決方法(屬於 Web SSO )。服務器
CAS 開始於 2001 年, 並在 2004 年 12 月正式成爲 JA-SIG 的一個項目。cookie
一、 開源的、多協議的 SSO 解決方案; Protocols : Custom Protocol 、 CAS 、 OAuth 、 OpenID 、 RESTful API 、 SAML1.1 、 SAML2.0 等。
二、 支持多種認證機制: Active Directory 、 JAAS 、 JDBC 、 LDAP 、 X.509 Certificates 等;
三、 安全策略:使用票據( Ticket )來實現支持的認證協議;
四、 支持受權:能夠決定哪些服務能夠請求和驗證服務票據( Service Ticket );
五、 提 供高可用性:經過把認證過的狀態數據存儲在 TicketRegistry 組件中,這些組件有不少支持分佈式環境的實現, 如: BerkleyDB 、 Default 、 EhcacheTicketRegistry 、 JDBCTicketRegistry 、 JBOSS TreeCache 、 JpaTicketRegistry 、 MemcacheTicketRegistry 等;
六、 支持多種客戶端: Java 、 .Net 、 PHP 、 Perl 、 Apache, uPortal 等。
本文內容主要針對 Web SSO 。
單點登陸( Single Sign-On , 簡稱 SSO )是目前比較流行的服務於企業業務整合的解決方案之一, SSO 使得在多個應用系統中,用戶只須要 登陸一次 就能夠訪問全部相互信任的應用系統。
通常 SSO 體系主要角色有三種:
一、 User (多個)
二、 Web 應用(多個)
三、 SSO 認證中心( 1 個 )
SSO 實現模式通常包括如下三個原則:
一、 全部的認證登陸都在 SSO 認證中心進行;
二、 SSO 認證中心經過一些方法來告訴 Web 應用當前訪問用戶到底是不是已經過認證的用戶;
三、 SSO 認證中心和全部的 Web 應用創建一種信任關係,也就是說 web 應用必須信任認證中心。(單點信任)
SSO 的主要實現方式有:
一、 共享 cookies
基 於共享同域的 cookie 是 Web 剛開始階段時使用的一種方式,它利用瀏覽同域名之間自動傳遞 cookies 機制,實現兩個域名之間系統令牌 傳遞問題;另外,關於跨域問題,雖然 cookies自己不跨域,但能夠利用它實現跨域的 SSO 。如:代理、暴露 SSO 令牌值等。
缺點:不靈活並且有很多安全隱患,已經被拋棄。
二、 Broker-based( 基於經紀人 )
這 種技術的特色就是,有一個集中的認證和用戶賬號管理的服務器。經紀人給被用於進一步請求的電子身份存取。中央數據庫的使用減小了管理的代價,併爲認證提供 一個公共和獨立的 "第三方 " 。例如 Kerberos 、 Sesame 、 IBM KryptoKnight (憑證庫思想 ) 等。 Kerberos是由麻省理工大學發明的安全認證服務,已經被 UNIX 和 Windows 做爲 默認的安全認證服務集成進操做系統。
三、 Agent-based (基於代理人)
在 這種解決方案中,有一個自動地爲不一樣的應用程序認證用戶身份的代理程序。這個代理程序須要設計有不一樣的功能。好比,它可使用口令表或加密密鑰來自動地將 認證的負擔從用戶移開。代理人被放在服務器上面,在服務器的認證系統和客戶端認證方法之間充當一個 " 翻譯 "。例如 SSH 等。
四、 Token-based
例如 SecureID,WebID ,如今被普遍使用的口令認證,好比 FTP 、郵件服務器的登陸認證,這是一種簡單易用的方式,實現一個口令在多種應用當中使用。
五、 基於網關
六、 基於 SAML
SAML(Security Assertion Markup Language ,安全斷言標記語言)的出現大大簡化了 SSO ,並被 OASIS 批准爲 SSO 的執行標準 。開源組織 OpenSAML 實現了 SAML 規範。
從結構體系看, CAS 包括兩部分: CAS Server 和 CAS Client 。
CAS Server 負責完成對用戶的認證工做 , 須要獨立部署 , CAS Server 會處理用戶名 / 密碼等憑證(Credentials) 。
負責處理對客戶端受保護資源的訪問請求,須要對請求方進行身份認證時,重定向到 CAS Server 進行認證。(原則上,客戶端應用再也不接受任何的用戶名密碼等 Credentials )。
CAS Client 與受保護的客戶端應用部署在一塊兒,以 Filter 方式保護受保護的資源。
基礎模式 SSO 訪問流程主要有如下步驟:
1. 訪問服務: SSO 客戶端發送請求訪問應用系統提供的服務資源。
2. 定向認證: SSO 客戶端會重定向用戶請求到 SSO 服務器。
3. 用戶認證:用戶身份認證。
4. 發放票據: SSO 服務器會產生一個隨機的 Service Ticket 。
5. 驗證票據: SSO 服務器驗證票據 Service Ticket 的合法性,驗證經過後,容許客戶端訪問服務。
6. 傳輸用戶信息: SSO 服務器驗證票據經過後,傳輸用戶認證結果信息給客戶端。
下面是 CAS 最基本的協議過程:
基礎協議圖
如 上圖: CAS Client 與受保護的客戶端應用部署在一塊兒,以 Filter 方式保護 Web 應用的受保護資源,過濾從客戶端過來的每個 Web 請求,同 時, CAS Client 會分析 HTTP 請求中是否包含請求 Service Ticket( ST 上圖中的 Ticket) ,若是沒有,則說明該用戶是沒有通過認證的;因而 CAS Client 會重定向用戶請求到 CAS Server ( Step 2 ),並傳遞 Service (要訪問的目的資源地址)。 Step 3 是用戶認證過程,若是用戶提供了正確的 Credentials , CAS Server 隨機產生一個至關長度、惟1、不可僞造的 Service Ticket ,並緩存以待未來驗證,而且重定向用戶到 Service 所在地址(附帶剛纔產生的 Service Ticket ) , 併爲客戶端瀏覽器設置一個 Ticket Granted Cookie ( TGC ) ; CAS Client 在拿到 Service 和新產生的 Ticket 事後,在 Step 5 和 Step6 中與 CAS Server 進行身份覈實,以確保 Service Ticket 的合法性。
在該協議中,全部與 CAS Server 的交互均採用 SSL 協議,以確保 ST 和 TGC 的安全性。協議工做過程當中會有 2 次重定向 的過程。可是 CAS Client 與 CAS Server 之間進行 Ticket 驗證的過程對於用戶是透明的(使用 HttpsURLConnection )。
CAS 請求認證時序圖以下:
當用戶訪問另外一個應用的服務再次被重定向到 CAS Server 的時候, CAS Server 會主動獲到這個 TGC cookie ,而後作下面的事情:
1) 若是 User 持有 TGC 且其還沒失效,那麼就走基礎協議圖的 Step4 ,達到了 SSO 的效果;
2) 若是 TGC 失效,那麼用戶仍是要從新認證 ( 走基礎協議圖的 Step3) 。
該模式形式爲用戶訪問 App1 , App1 又依賴於 App2 來獲取一些信息,如: User -->App1 -->App2。
這 種狀況下,假設 App2 也是須要對 User 進行身份驗證才能訪問,那麼,爲了避免影響用戶體驗(過多的重定向致使 User 的 IE 窗口不停地 閃動 ) , CAS 引入了一種 Proxy 認證機制,即 CAS Client 能夠代理用戶去訪問其它 Web 應用。
代 理的前提是須要 CAS Client 擁有用戶的身份信息 ( 相似憑據 ) 。以前咱們提到的 TGC 是用戶持有對本身身份信息的一種憑據,這裏的 PGT 就是 CAS Client 端持有的對用戶身份信息的一種憑據。憑藉TGC , User 能夠免去輸入密碼以獲取訪問其它服務的 Service Ticket ,因此,這裏憑藉 PGT , Web應用能夠代理用戶去實現後端的認證,而 無需前端用戶的參與 。
下面爲代理應用( helloService )獲取 PGT 的過程: (注: PGTURL 用於表示一個 Proxy 服務,是一個回調連接; PGT 至關於代理證; PGTIOU 爲取代理證的鑰匙,用來與 PGT 作關聯關係;)
如上面的 CAS Proxy 圖所示, CAS Client 在基礎協議之上,在驗證 ST 時提供了一個額外的PGT URL( 並且是 SSL 的入口 ) 給 CAS Server ,使得 CAS Server 能夠經過 PGT URL 提供一個 PGT 給 CAS Client 。
CAS Client 拿到了 PGT(PGTIOU-85 … ..ti2td) ,就能夠經過 PGT 向後端 Web 應用進行認證。
下面是代理認證和提供服務的過程:
如 上圖所示, Proxy 認證與普通的認證其實差異不大, Step1 , 2 與基礎模式的 Step1,2 幾乎同樣,惟一不一樣的 是, Proxy 模式用的是 PGT 而不是 TGC ,是 Proxy Ticket ( PT )而不是 Service Ticket 。
CAS 的 SSO 實現方式可簡化理解爲: 1 個 Cookie 和 N 個 Session 。 CAS Server 建立 cookie,在全部應用認證時使用,各應用經過建立各自的 Session 來標識用戶是否已登陸。
用 戶在一個應用驗證經過後,之後用戶在同一瀏覽器裏訪問此應用時,客戶端應用中的過濾器會在 session 裏讀取到用戶信息,因此就不會去 CAS Server 認證。若是在此瀏覽器裏訪問別的 web 應用時,客戶端應用中的過濾器在 session 裏讀取不到用戶信息,就會去 CAS Server 的 login 接口認證,但這時CAS Server 會讀取到瀏覽器傳來的 cookie ( TGC ),因此 CAS Server 不會要求用戶去登陸頁面登陸,只是會根據 service 參數生成一個 Ticket ,而後再和 web 應用作一個驗 證 ticket 的交互而已。
CAS 系統中設計了 5 中票據: TGC 、 ST 、 PGT 、 PGTIOU 、 PT 。
Ø Ticket-granting cookie(TGC) :存放用戶身份認證憑證的 cookie ,在瀏覽器和 CAS Server 間通信時使用,而且只能基於安全通道傳輸( Https ),是 CAS Server 用來明確用戶身份的憑證;
Ø Service ticket(ST) :服務票據,服務的唯一標識碼 , 由 CAS Server 發出( Http 傳送),經過客戶端瀏覽器到達業務服務器端;一個特定的服務只能有一個唯一的 ST ;
Ø Proxy-Granting ticket ( PGT ):由 CAS Server 頒發給擁有 ST 憑證的服務, PGT 綁定一個用戶的特定服務,使其擁有向 CAS Server 申請,得到 PT 的能力;
Ø Proxy-Granting Ticket I Owe You ( PGTIOU ) : 做用是將經過憑證校驗時的應答信息由 CAS Server 返回給 CAS Client ,同時,與該 PGTIOU 對應的 PGT 將經過回調連接傳給 Web 應用。 Web 應用負責維護 PGTIOU 與 PGT 之 間映射關係的內容表;
Ø Proxy Ticket (PT) :是應用程序代理用戶身份對目標程序進行訪問的憑證;
其它說明以下:
Ø Ticket Granting ticket(TGT) :票據受權票據,由 KDC 的 AS 發放。即獲取這樣一張票據後,之後申請各類其餘服務票據 (ST) 便沒必要再向 KDC 提交身份認證信息 (Credentials) ;
Ø Authentication service(AS) --------- 認證用服務,索取 Credentials ,發放 TGT ;
Ø Ticket-granting service (TGS) --------- 票據受權服務,索取 TGT ,發放 ST ;
Ø KDC( Key Distribution Center ) ---------- 密鑰發放中心;
第一步:
cas往瀏覽器增長cookie(TGC)
CAS向瀏覽器送回一個所謂的「內存cookie」。這種cookie並非真的保存在內存中,而只是瀏覽器一關閉,cookie就自動過時。這個cookie稱爲「ticket-granting cookie」,用來代表用戶已經成功地登陸。
這個Cookie是一個加密的Cookie,其中保存了用戶登陸的信息。用於之後其它應用客戶端登陸。
第二步:
cas同時建立一個ticket重定向到原來的cas客戶端
認證成功後,CAS服務器建立一個很長的、隨機生成的字符串,稱爲「Ticket」。隨後,CAS將這個ticket和成功登陸的用戶,以及服務聯繫在一塊兒。這個ticket是一次性使用的一種憑證,它只對登陸成功的用戶及其服務使用一次。使用過之後馬上失效。
第一步:
收到ticket後,向cas提交驗證ticket
Cas客戶端收到ticket以後,應用程序須要驗證ticket。這是經過將ticket 傳遞給一個校驗URL來實現的。校驗URL也是CAS服務器提供的。CAS經過校驗路徑得到了ticket以後,經過內部的數據庫對其進行判斷。若是判斷是有效性,則返回一個NetID給應用程序。隨後CAS將ticket做廢,而且在客戶端留下一個cookie。(誰來建立cookie?),
第二步:
ticket驗證後建立session之後登陸此應用時,沒有ticket,但IE能提供session,從session中取得CASReceipt,並驗證若是有效說明已經在此應用認證過,容許訪問此應用,到此爲止,CAS會記錄用戶已在應用A已經登陸
用戶進入應用B時,首先仍然會重定向到CAS服務器。不過此時CAS服務器再也不要求用戶輸 入用戶名和密碼,而是首先自動尋找Cookie,根據Cookie中保存的信息,進行登陸。而後,CAS一樣給出新的ticket重定向應用B給cas驗證(流程同應用A驗證方式),若是驗證成功則應用B建立session記錄CASReceipt信息到session中,之後憑此session登陸應用B。
到此爲止,CAS會記錄用戶已在應用A和應用B進行登陸,可是當用戶在應用B退出cas登陸時,要通知應用A進行退出,如何通知應用A呢?
CAS server接受請求後,會檢測用戶的TCG Cookie,把對應的session清除,同時會找到全部經過該TGC sso登陸的應用服務器URL提交請求,全部收到請求的應用服務器application會解析這個參數,取得sessionId,根據這個Id取得session後,把session刪除。
這樣就實現單點登出的功能。
CAS 的安全性僅僅依賴於 SSL 。使用的是 secure cookie 。
對於一個 CAS 用戶來講,最重要是要保護它的 TGC ,若是 TGC 不慎被 CAS Server 之外的實體得到, Hacker 可以找到該 TGC ,而後冒充 CAS 用戶訪問 全部 受權資源。 PGT 的角色跟 TGC 是同樣的。
從基礎模式能夠看出, TGC 是 CAS Server 經過 SSL 方式發送給終端用戶,所以,要截取 TGC 難度很是大,從而確保 CAS 的安全性。
TGT 的存活週期默認爲 120 分鐘。
ST ( Service Ticket )是經過 Http 傳送的,所以網絡中的其餘人能夠 Sniffer 到其餘人的 Ticket 。 CAS 經過如下幾方面來使 ST 變得更加安全(事實上都是能夠配置的):
一、 ST 只能使用一次
CAS 協議規定,不管 Service Ticket 驗證是否成功, CAS Server 都會清除服務端緩存中的該Ticket ,從而能夠確保一個 Service Ticket 不被使用兩次。
二、 ST 在一段時間內失效
CAS 規定 ST 只能存活必定的時間,而後 CAS Server 會讓它失效。默認有效時間爲 5 分鐘。
三、 ST 是基於隨機數生成的
ST 必須足夠隨機,若是 ST 生成規則被猜出, Hacker 就等於繞過 CAS 認證,直接訪問 對應的服務。
1. 第一次訪問 http://localhost:8080/A
CLIENT:沒票據且SESSION中沒有消息因此跳轉至CAS
CAS:拿不到TGC故要求用戶登陸
2. 認證成功後回跳
CAS:經過TGT生成ST發給客戶端,客戶端保存TGC,並重定向到http://localhost:8080/A
CLIENT:帶有票據因此不跳轉只是後臺發給CAS驗證票據(瀏覽器中沒法看到這一過程)
3. 第一次訪問 http://localhost:8080/B
CLIENT:沒票據且SESSION中沒有消息因此跳轉至CAS
CAS:從客戶端取出TGC,若是TGC有效則給用戶ST並後臺驗證ST,從而SSO。【若是失效重登陸或註銷時,怎麼通知其它系統更新SESSION信息呢??
TicketGrantingTicketImpl類grantServiceTicket方法裏this.services.put(id,service);可見CAS端已經記錄了當前登陸的子系統】
4. 再次訪問 http://localhost:8080/A
CLIENT:沒票據可是SESSION中有消息故不跳轉也不用發CAS驗證票據,容許用戶訪問