CAS協議原理與代碼實現(單點登錄 與 單點登出的流程)


傳統方式及弊端

將 userinfo 寫入Cookie,首先不安全,最重要的是 無法跨域 (cookie是和域綁定的)。CAS協議就是為實現單點登錄而誕生的。

CAS協議原理

Yale 大學發起的一個開源項目(基於Java)

CAS Server 為獨立部署的 Web 應用

CAS Client 支持多種客戶端

概念解釋

單點登錄(Single sign-on, SSO):在多個應用系統中,用戶只需要登錄一次就可以訪問所有相互信任的應用系統。

統一用戶:多個應用共用一套帳號體系,統一用戶是 單點登錄 的實現前提。一般,儲存用戶的公有屬性在中央認證服務器。

局部會話(Application Session):業務系統服務器(豆瓣讀書、電影等服務器)與 瀏覽器 的會話。

全局會話(CAS Session):CAS認證服務器(用戶中心)與 瀏覽器 的會話。

Service:業務系統的路由,提前在 CAS認證服務器注冊過。

Ticket Granted Ticket — TGT:大令牌,記錄某用戶全局會話的狀態。

CASTGC — TGC:Ticket Granting Cookie,TGT記錄在Cookie中的內容,一般是TGT的id。

Service Ticket— ST:小令牌,用來向CAS認證服務器(用戶中心)兌換用戶信息。一般,限制使用次數或有效期。

組成部分

CAS Server:主要負責對用戶的認證工作。(用戶中心)

CAS Client :負責處理對客戶端受保護資源的訪問請求,登錄時,重定向到 CAS Server。(各業務系統,豆瓣讀書、電影等)

基本流程

A 訪問服務:用戶瀏覽器請求訪問 業務系統(讀書、電影等)。
B 定向認證:業務系統 引導瀏覽器 重定向 到CAS認證服務器(用戶中心)。
C 用戶登錄:用戶在 用戶中心 完成登錄,全局會話記錄此次登陸。
D 發放票據:CAS服務器產生Service Ticket,並 重定向 到業務系統。
E 兌換信息:業務系統用Service Ticket 向CAS服務器 兌換用戶信息。

CAS協議的具體流程及細節

建立單點登錄,首次訪問豆瓣

A: 瀏覽器請求訪問 豆瓣讀書。
B: 豆瓣讀書 引導瀏覽器 重定向 到 豆瓣用戶中心。

攜帶 Service參數

C: 在用戶中心完成登錄,建立全局會話。

驗證Service

生成TGT-在瀏覽器記錄CASTGC,即TGT.id,即 建立全局會話

D: CAS服務器產生Service Ticket,並 重定向 到業務系統。

用TGT 簽發 ST

重定向到 Service代表的 豆瓣讀書 路由,並攜帶 ST

E: 豆瓣讀書 用Service Ticket 向 用戶中心服務器 兌換用戶信息。

豆瓣讀書服務器獲取 ST

豆瓣讀書在后台用 ST 向 用戶中心服務器 兌換用戶信息,官方使用xml傳輸信息(本文用JSON代替)

兌換成功后,豆瓣讀書 用Session或Cookie 記錄用戶的登錄狀態,即 建立局部會話。

第二次訪問豆瓣讀書

A: 請求攜帶Session,豆瓣讀書判斷局部會話有效,即完成登錄。首次訪問豆瓣電影與首次訪問豆瓣讀書的流程一樣

B: 豆瓣用戶中心服務器 驗證TGT,判斷 全局會話是否存在。請求攜帶存有CASTGC的Cookie(服務端的域下面)

用CASTGC驗證TGT,通過后,即可完成用戶登錄,接着簽發ST


以上只是單點登錄的流程,完整的單點登錄還應該支持單點登出(Single Logout, SLO)

單點登出(SLO)

  CAS項目及協議支持單點登出,但是並未給出詳細的流程圖,作者是根據CAS2.x與CAS3.x的指南文檔進行歸納總結得出結論。

A: 瀏覽器請求 豆瓣讀書的 /logout,豆瓣讀書 刪除Session相關內容,即清除局部會話。

B: 豆瓣讀書 引導瀏覽器重定向到 用戶中心的 /logout,攜帶Cookie中的CASTGC

C: 清除全局會話,刪除 Cookie中的CASTGC,注銷 TGC對應的TGT

D: 認證服務器 通知所有已登錄的業務系統清除局部會話,找到TGT簽發的ST,即所有已登錄的業務系統(豆瓣電影、音樂),在后台,通知 所有有關的業務系統(Fire & Forget),攜帶ST

E: 業務系統 接到通知后 清除局部會話,用ST 清除 對應的Session,即 清除對應的局部會話

數據庫

CAS認證服務器

User:用戶表

username:用戶名
password:密碼
Service:業務系統的服務接入表
url:Service的業務路由
logout_url:Service的退出路由 

TGT:大令牌表
tgt:ticket_granted_ticket, 大令牌
user_id:User.id
expires_in:過期時間
validate:是否有效(-1:無效,1:有效)

ST:小令牌表
st:service_ticket, 小令牌
user_id:User.id
tgt_id:TGT.id,由哪個TGT簽發
service_id:Service.id
used:使用次數,一般限制使用次數
expires_in:過期時間
validate:是否有效(-1:無效,1:有效)

Client服務器

Info:信息表,代表該服務器的用戶資源
username:用戶名
info:資源

 

ST:小令牌表,業務系統記錄ST的狀態,用於根據ST刪除對應的Session

st:service_ticket, 小令牌
validate:是否有效(-1:無效,1:有效)

關鍵點與擴展

CAS認證服務器需要驗證Service的有效性(提前注冊),避免被攻擊。

TGT只是代表用戶登錄,不對應Service。而ST對應Service。

SLO,業務系統收到CAS認證服務器通知后,根據ST來刪除對應的Session,本文只是在 Client數據庫 注銷了對應的ST。因為,每次登陸時,會驗證ST有效性。

SLO的業務系統可以根據具體業務需要不支持清除局部會話,比如郵件等業務。

Flask的原生session機制是存儲在瀏覽器,而不是通常session存儲在服務器,可以利用flask_session重構session存儲機制,或 定制flask的session模塊代碼。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM