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

2023-04-13 18:00:56

作者:京東物流 趙勇萍

前言

上個月我負責的系統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」: [email protected],
      「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協定哦。