CAS協議和工作流程下圖是 CAS 最基礎協議:
1 、 CAS Client 與受保護的客戶端應用部署在一起,以 Filter 方式保護受保護的資源。對於訪問受保護資源的每個 Web 請求, CAS Client 會分析該請求的 Http 請求中是否包含 Service Ticket ( ST )和 Ticket Granting tieckt(TGT) ,如果沒有,則說明當前用戶尚未登錄,於是將請求重定向到指定好的 CAS Server 登錄地址,並傳遞 Service (也就是要訪問的目的資源地址),以便登錄成功過後轉回該地址。用戶在第 3 步中輸入認證信息,如果登錄成功, CAS Server 隨機產生一個相當長度、唯一、不可僞造的 Service Ticket ,並緩存以待將來驗證,之後系統自動重定向到 Service 所在地址,併爲客戶端瀏覽器設置一個 Ticket Granted Cookie ( TGC ), CAS Client 在拿到 Service 和新產生的 Ticket 過後,在第 5 , 6 步中與 CAS Server 進行身份覈實,以確保 Service Ticket 的合法性。
2 、在該協議中,所有與 CAS 的交互均採用 SSL 協議確保 ST 和 TGC 的安全性。協議工作過程中會有 2 次重定向的過程,但是 CAS Client 與 CAS Server 之間進行 Ticket 驗證的過程對於用戶是透明的。
3 、 CAS 如何實現 SSO
當用戶訪問另一服務再次被重定向到 CAS Server 的時候, CAS Server 會主動獲到這個 TGC cookie ,然後做下面的事情:
1) 如果 User 的持有 TGC 且其還沒失效,那麼就走基礎協議圖的 Step4 ,達到了 SSO 的效果;2) 如果 TGC 失效,那麼用戶還是要重新認證 ( 走基礎協議圖的 Step3) 。
另外,CAS 協議中還提供了 Proxy (代理)模式,以適應更加高級、複雜的應用場景,具體介紹可以參考 CAS 官方網站上的相關文檔。
OAuth 2.0的運行流程如下圖
摘自RFC 6749。
(A)用戶打開客戶端以後,客戶端要求用戶給予授權。
(B)用戶同意給予客戶端授權。
(C)客戶端使用上一步獲得的授權,向認證服務器申請令牌。
(D)認證服務器對客戶端進行認證以後,確認無誤,同意發放令牌。
(E)客戶端使用令牌,向資源服務器申請獲取資源。
(F)資源服務器確認令牌無誤,同意向客戶端開放資源。
不難看出來,上面六個步驟之中,B是關鍵,即用戶怎樣才能給於客戶端授權。有了這個授權以後,客戶端就可以獲取令牌,進而憑令牌獲取資源。
下面一一講解客戶端獲取授權的四種模式。
四種授權方式
OAuth 2.0定義了四種授權方式。
- 密碼模式(resource owner password credentials)
- 授權碼模式(authorization code)
- 簡化模式(implicit)
- 客戶端模式(client credentials)
密碼模式(
resource owner password credentials
)(爲遺留系統設計
)(支持refresh token
)- 這種模式是最不推薦的,因爲client可能存了用戶密碼
- 這種模式主要用來做遺留項目升級爲oauth2的適配方案
- 當然如果client是自家的應用,也是可以
- 支持refresh token
授權碼模式(
authorization code
)(正宗方式
)(支持refresh token
)- 這種模式算是正宗的oauth2的授權模式
- 設計了auth code,通過這個code再獲取token
- 支持refresh token
簡化模式(
implicit
)(爲web瀏覽器應用設計
)(不支持refresh token
)- 這種模式比授權碼模式少了code環節,回調url直接攜帶token
- 這種模式的使用場景是基於瀏覽器的應用
- 這種模式基於安全性考慮,建議把token時效設置短一些
- 不支持refresh token
客戶端模式(
client credentials
)(爲後臺api服務消費者設計
)(不支持refresh token
)- 這種模式直接根據client的id和密鑰即可獲取token,無需用戶參與
- 這種模式比較合適消費api的後端服務,比如拉取一組用戶信息等
- 不支持refresh token,主要是沒有必要
refresh token的初衷主要是爲了用戶體驗不想用戶重複輸入賬號密碼來換取新token,因而設計了refresh token用於換取新token
這種模式由於沒有用戶參與,而且也不需要用戶賬號密碼,僅僅根據自己的id和密鑰就可以換取新token,因而沒必要refresh token
- cas(單點登錄)
現象:多個系統只需登錄一次,無需重複登錄
原理:授權服務器,被授權客戶端
1、授權服務器(一個)保存了全局的一份session,客戶端(多個)各自保存自己的session
2、客戶端登錄時判斷自己的session是否已登錄,若未登錄,則(告訴瀏覽器)重定向到授權服務器(參數帶上自己的地址,用於回調)
3、授權服務器判斷全局的session是否已登錄,若未登錄則定向到登錄頁面,提示用戶登錄,登錄成功後,授權服務器重定向到客戶端(參數帶上ticket【一個憑證號】)
4、客戶端收到ticket後,請求服務器獲取用戶信息
5、服務器同意客戶端授權後,服務端保存用戶信息至全局session,客戶端將用戶保存至本地session - oauth2(登錄授權)
現象:第三方系統訪問主系統資源,用戶無需將在主系統的賬號告知第三方,只需通過主系統的授權,第三方就可使用主系統的資源(如:APP1需使用微信支付,微信支付會提示用戶是否授權,用戶授權後,APP1就可使用微信支付功能了)
原理:主系統,授權系統(給主系統授權用的,也可以跟主系統是同一個系統),第三方系統
1、第三方系統需要使用主系統的資源,第三方重定向到授權系統
2、根據不同的授權方式,授權系統提示用戶授權
3、用戶授權後,授權系統返回一個授權憑證(accessToken)給第三方系統【accessToken是有有效期的】
4、第三方使用accessToken訪問主系統資源【accessToken失效後,第三方需重新請求授權系統,以獲取新的accessToken】 - 單一登錄
現象:同一系統,同一用戶在同一時間內只能有一個會話(即一個用戶只有一個在使用的瀏覽器)
原理:
1、把登錄成功的用戶放入session和緩存,緩存中格式:key:userID,value:sessionId
2、用戶訪問資源時,用攔截器(或過濾器)攔截用戶請求,先判斷用戶是否已登錄(根據session判斷),若用戶未登錄,則定向到登錄頁面提示用戶登錄
3、若用戶session已登錄,根據用戶userID取出緩存數據,判斷當前瀏覽器的sessionId與緩存的是否一致,若一致,則繼續訪問
4、若sessionId不一致,則將當期的session數據清空,用戶登出,提示用戶被踢出