作者:京東物流 趙勇萍
上個月我負責的系統SSO升級,對接京東ERP系統,這也讓我想起了之前我做過一個單點登入的專案。想來單點登入有很多實現方案,不過最主流的還是基於CAS的方案,所以我也就分享一下我的CAS實踐之路。
單點登入的英文名叫做:Single Sign On(簡稱SSO)。SSO的定義是在多個應用系統中,使用者只需要登入一次就可以存取所有相互信任的應用系統。之前我做的系統,需要需要設計一套支援單點登入的鑑權認證系統,所有系統都基於一套鑑權系統進行登入,並且可以實現各個系統之間的互信和跳轉。所以就採用了CAS架構。
CAS架構的核心是需要搭建一個CAS Server,該服務獨立部署,擁有獨立三級域名,主要負責對使用者的認證工作。他主要組成包括WEB前端提供登入頁面,票據模組,認證模組。
核心票據:
a. TGT(Ticket Grangting Ticket):TGT是CAS為使用者簽發的登入票據,有TGT就表明使用者在CAS上成功登入過。使用者在CAS認證成功後,會生成一個TGT物件,放入自己的快取中(Session),同時生成TGC以cookie的形式寫入瀏覽器。當再次存取CAS時,會先看cookie中是否存在TGC,如果存在則通過TGC獲取TGT,如果獲取到了TGT則代表使用者之前登入過,通過TGT及存取來源生成針對來源的ST,使用者就不用再次登入,以此來實現單點登入。
b. TGC(Ticket-granting cookie):TGC就是TGT的唯一標識,以cookie的形式存在在CAS Server三級域名下,是CAS Server 用來明確使用者身份的憑證。
c. ST(Service Ticket):ST是CAS為使用者簽發的存取某一使用者端的服務票據。使用者存取service時,service發現使用者沒有ST,就會重定向到 CAS Server 去獲取ST。CAS Server 接收到請求後,會先看cookie中是否存在TGC,如果存在則通過TGC獲取TGT,如果獲取到了TGT則代表使用者之前登入過,通過TGT及存取來源生成針對來源的ST。使用者憑藉ST去存取service,service拿ST 去CAS Server 上進行驗證,驗證通過service生成使用者session,並返回資源。
在我負責的專案系統中,後臺業務採用的是微服務架構,有統一的業務閘道器,所以基於統一的業務閘道器,整合客戶其他系統登入鑑權流程。具體業務架構圖如下:
在此說明一下,因為登入系統的使用者體系在不同的系統中,所以我在設計SSO統一登入認證的時候,把SSO系統與業務系統結構出來。而使用者體系有兩套,一套叫做採方使用者體系,一套叫做供方使用者體系。所以才會有如圖所示的SSO Server服務,他本身不負責使用者管理,但會通過統一標準介面的方式實現控制反轉,實現對使用者服務的呼叫。
時序圖如下:
如圖所示,時序圖示識的是兩個系統通過SSO服務,實現了單點登入。
呼叫說明:
由應用側發起呼叫認證中心的介面。
URL地址:
https:// sso.com?appId=***&tenantType=1&redirectUri=***
請求方式:302重定向
引數說明:
appId: 對接SSO認證中心的應用唯一標識,由SSO認證中心通過線下的方式頒發給各個應用系統。
tenantType: 標記是供方登入還是採方登入。採方為1,供方為2.
RedirectUri: 應用回撥地址。
呼叫說明:
有認證中心發起,應用側需實現的介面。認證中心通過302重定向,將code傳給應用側,應用側自行發起通過臨時令牌code換取accessTokenInfo。
URL地址:
https://應用域名?code=***
請求方式:GET
引數說明:
Code: 臨時令牌,有效時間5min
呼叫說明
由應用側發起呼叫認證中心的介面。通過該介面可以獲取accessTokenInfo資訊,然後系統自行生成本系統session資訊。
URL地址:
https://sso.com/api/token/create?grantType=authorization_code&appId=yuncai&code=***
請求方式:GET
引數說明:
appId: 對接SSO認證中心的應用唯一標識,由SSO認證中心通過線下的方式頒發給各個應用系統。
code: 臨時令牌,需加密
加密規則如下:
Code先進行base64加密
用認證中心給的privateKey進行加密(RSA加密)。
加密後進行URLCode轉碼。
返回引數:
{
「accessToken」: 「****」, //token令牌
「expiresIn」: 7200, //過期時間
「user」: {
「username」: 「zhangsan」,
「fullName」: 「張三」,
「userId」: 「1212」,
「phone」: 「13100000000」,
「email」: [email protected],
「tenantId」: 「S2131123」,
「tenantType」: 1
}
}
呼叫說明:
由應用側發起呼叫認證中心的介面。當token快到失效期時,通過該介面可以重新整理accessTokenInfo資訊,然後系統自行生成本系統session資訊。
URL地址:
https://sso.com/api/token/refresh?appId=yuncai&accessToken=***
請求方式:GET
引數說明:
appId: 對接SSO認證中心的應用唯一標識,由SSO認證中心通過線下的方式頒發給各個應用系統。
accessToken: 需要重新整理的token值。
有單點登入,也會有單點登出,這樣才會形成業務閉環,對於單點登出邏輯,基本類似登入的逆操作,時序圖如下:
呼叫說明:
由應用側發起呼叫認證中心的介面。
URL地址:
https://sso.com/logout?redirectUri=***
請求方式:GET
引數說明
RedirectUri: 應用回撥地址。
呼叫說明
有認證中心發起,應用側需實現的介面。通過該介面觸發個應用系統清除快取和session相關資訊,實現系統登出。
URL地址:
https://應用系統域名/ssoLogout
請求方式:GET
header: logoutRequest:=accessToken
對於CAS這種單點登入的架構,他是非常依賴於cookie的安全性的。所以CAS的安全性也在一定程度上取決於cookie的安全性,所有增強cookie安全性的措施,對於增強CAS都是有效的。
最後提一句,一定要使用HTTPS協定哦。