【實踐篇】基於CAS的單點登入實踐之路

京東雲開發者發表於2023-04-13

作者:京東物流 趙勇萍

前言

上個月我負責的系統SSO升級,對接京東ERP系統,這也讓我想起了之前我做過一個單點登入的專案。想來單點登入有很多實現方案,不過最主流的還是基於CAS的方案,所以我也就分享一下我的CAS實踐之路。

什麼是單點登入

單點登入的英文名叫做:Single Sign On(簡稱SSO)。SSO的定義是在多個應用系統中,使用者只需要登入一次就可以訪問所有相互信任的應用系統。之前我做的系統,需要需要設計一套支援單點登入的鑑權認證系統,所有系統都基於一套鑑權系統進行登入,並且可以實現各個系統之間的互信和跳轉。所以就採用了CAS架構。

什麼是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,並返回資源。

基於CAS的系統實踐方案

1. 業務背景

在我負責的專案系統中,後臺業務採用的是微服務架構,有統一的業務閘道器,所以基於統一的業務閘道器,整合客戶其他系統登入鑑權流程。具體業務架構圖如下:

在此說明一下,因為登入系統的使用者體系在不同的系統中,所以我在設計SSO統一登入認證的時候,把SSO系統與業務系統結構出來。而使用者體系有兩套,一套叫做採方使用者體系,一套叫做供方使用者體系。所以才會有如圖所示的SSO Server服務,他本身不負責使用者管理,但會透過統一標準介面的方式實現控制反轉,實現對使用者服務的呼叫。

2. 單點登入時序圖

時序圖如下:

如圖所示,時序圖示識的是兩個系統透過SSO服務,實現了單點登入。

3. 單點登入核心介面說明

3.1 sso認證跳轉介面

呼叫說明:

由應用側發起呼叫認證中心的介面。

URL地址:

https:// sso.com?appId=***&tenantType=1&redirectUri=***

請求方式:302重定向

引數說明:

appId: 對接SSO認證中心的應用唯一標識,由SSO認證中心透過線下的方式頒發給各個應用系統。

tenantType: 標記是供方登入還是採方登入。採方為1,供方為2.

RedirectUri: 應用回撥地址。

3.2 重定向獲取臨時令牌code介面

呼叫說明:

有認證中心發起,應用側需實現的介面。認證中心透過302重定向,將code傳給應用側,應用側自行發起透過臨時令牌code換取accessTokenInfo。

URL地址:

https://應用域名?code=***

請求方式:GET

引數說明:

Code: 臨時令牌,有效時間5min

3.3 獲取accessTokenInfo介面

呼叫說明

由應用側發起呼叫認證中心的介面。透過該介面可以獲取accessTokenInfo資訊,然後系統自行生成本系統session資訊。

URL地址:

https://sso.com/api/token/create?grantType=authorization_code&appId=yuncai&code=***

請求方式:GET

引數說明:

appId: 對接SSO認證中心的應用唯一標識,由SSO認證中心透過線下的方式頒發給各個應用系統。

code: 臨時令牌,需加密

加密規則如下:

  1. Code先進行base64加密

  2. 用認證中心給的privateKey進行加密(RSA加密)。

  3. 加密後進行URLCode轉碼。

返回引數:

{
  “accessToken”:  “****”,  //token令牌
  “expiresIn”: 7200,        //過期時間
  “user”: {
    “username”: “zhangsan”,
       “fullName”: “張三”,
      “userId”: “1212”,
      “phone”: “13100000000”,
      “email”: zhangsan@test.com,
      “tenantId”: “S2131123”,
      “tenantType”: 1
  }
}


3.4 重新整理Token介面

呼叫說明:

由應用側發起呼叫認證中心的介面。當token快到失效期時,透過該介面可以重新整理accessTokenInfo資訊,然後系統自行生成本系統session資訊。

URL地址:

https://sso.com/api/token/refresh?appId=yuncai&accessToken=***

請求方式:GET

引數說明:

appId: 對接SSO認證中心的應用唯一標識,由SSO認證中心透過線下的方式頒發給各個應用系統。

accessToken: 需要重新整理的token值。

4. 單點登出邏輯

有單點登入,也會有單點登出,這樣才會形成業務閉環,對於單點登出邏輯,基本類似登入的逆操作,時序圖如下:

5. 單點登出核心介面說明

5.1 登出sso認證中心跳轉介面

呼叫說明:

由應用側發起呼叫認證中心的介面。

URL地址:

https://sso.com/logout?redirectUri=***

請求方式:GET

引數說明

RedirectUri: 應用回撥地址。

5.2 應用系統退出介面

呼叫說明

有認證中心發起,應用側需實現的介面。透過該介面觸發個應用系統清除快取和session相關資訊,實現系統登出。

URL地址:

https://應用系統域名/ssoLogout

請求方式:GET

 header: logoutRequest:=accessToken

總結

對於CAS這種單點登入的架構,他是非常依賴於cookie的安全性的。所以CAS的安全性也在一定程度上取決於cookie的安全性,所有增強cookie安全性的措施,對於增強CAS都是有效的。

最後提一句,一定要使用HTTPS協議哦。

相關文章