單點(diǎn)登錄 (SingleSign-On,SSO) ,是一種幫助用戶快捷訪問(wèn)網(wǎng)絡(luò)中多個(gè)站點(diǎn)的安全通信技術(shù)。單點(diǎn)登錄系統(tǒng)基于一種安全的通信協(xié)議,該協(xié)議通過(guò)多個(gè)系統(tǒng)之間的用戶身份信息的交換來(lái)實(shí)現(xiàn)單點(diǎn)登錄。使用單點(diǎn)登錄系統(tǒng)時(shí),用戶只需要登錄一次,就可以訪問(wèn)多個(gè)系統(tǒng),不需要記憶多個(gè)口令密碼。
云程平臺(tái)支持CAS、OAuth2、JWT三種主流的單點(diǎn)登錄技術(shù),客戶可根據(jù)需求選擇對(duì)應(yīng)技術(shù)方案。
一、CAS總體架構(gòu)介紹
CAS(Central Authentication Service)是 Yale大學(xué)發(fā)起的一個(gè)企業(yè)級(jí)的、開(kāi)源的項(xiàng)目,旨在為 Web 應(yīng)用系統(tǒng)提供一種可靠的單點(diǎn)登錄解決方法。CAS的目標(biāo)是允許用戶訪問(wèn)多個(gè)應(yīng)用程序只提供一次用戶憑據(jù)(如用戶名和密碼)。
CAS 體系包含兩個(gè)部分: CAS Server 和 CAS Client。CAS Server 需要獨(dú)立部署,主要負(fù)責(zé)對(duì)用戶的認(rèn)證工作;CAS Client 負(fù)責(zé)處理對(duì)客戶端受保護(hù)資源的訪問(wèn)請(qǐng)求,需要登錄時(shí),重定向到 CAS Server。
CAS 具有以下特點(diǎn):
- 一個(gè)開(kāi)放的,文檔齊全的協(xié)議。
- 開(kāi)源的JAVA服務(wù)器組件。
- CAS Client 支持非常多的客戶端(這里指單點(diǎn)登錄系統(tǒng)中的各個(gè) Web 應(yīng)用),包括 Java, .NET, php, Perl, Apache, uPortal, Ruby 等。
- 文檔社區(qū)化和實(shí)現(xiàn)的支持。
- 具有廣泛的客戶群的支持。
CAS官方文檔:https://apereo.github.io/cas/5.3.x/index.html#
二、CAS單點(diǎn)原理和集成流程
在 CAS 的整個(gè)登錄過(guò)程中,有三個(gè)重要的概念。
- TGT:TGT 全稱叫做 Ticket Granting Ticket,這個(gè)相當(dāng)于我們平時(shí)所見(jiàn)到的 HttpSession 的作用,用戶登錄成功后,用戶的基本信息,如用戶名、登錄有效期等信息,都將存儲(chǔ)在此。
- TGC:TGC 全稱叫做 Ticket Granting Cookie,TGC 以 Cookie 的形式保存在瀏覽器中,根據(jù) TGC 可以幫助用戶找到對(duì)應(yīng)的 TGT,所以這個(gè) TGC 有點(diǎn)類似與會(huì)話 ID。
- ST:ST 全稱是 Service Ticket,這是 CAS Sever 通過(guò) TGT 給用戶發(fā)放的一張票據(jù),用戶在訪問(wèn)其他服務(wù)時(shí),發(fā)現(xiàn)沒(méi)有 Cookie 或者 ST ,那么就會(huì) 302 到 CAS Server 獲取 ST,然后會(huì)攜帶著 ST 302 回來(lái),CAS Client 則通過(guò) ST 去 CAS Server 上獲取用戶的登錄狀態(tài)。
CAS的單點(diǎn)登錄SSO流程如下, 應(yīng)用系統(tǒng)要做單點(diǎn)登錄,需要跟CAS服務(wù)進(jìn)行集成,首先要理解CAS集成流程和原理。
- 用戶通過(guò)瀏覽器訪問(wèn)應(yīng)用1,應(yīng)用1 發(fā)現(xiàn)用戶沒(méi)有登錄,于是返回 302,并且攜帶上一個(gè) service 參數(shù),讓用戶去 CAS Server 上登錄。
- 瀏覽器自動(dòng)重定向到 CAS Server 上,CAS Server 獲取用戶 Cookie 中攜帶的 TGC,去校驗(yàn)用戶是否已經(jīng)登錄,如果已經(jīng)登錄,則完成身份校驗(yàn)(此時(shí) CAS Server 可以根據(jù)用戶的 TGC 找到 TGT,進(jìn)而獲取用戶的信息);如果未登錄,則重定向到 CAS Server 的登錄頁(yè)面,用戶輸入用戶名/密碼,CAS Server 會(huì)生成 TGT,并且根據(jù) TGT 簽發(fā)一個(gè) ST,再將 TGC 放在用戶的 Cookie 中,完成身份校驗(yàn)。
- CAS Server 完成身份校驗(yàn)之后,會(huì)將 ST 拼接在 service 中,返回 302,瀏覽器將首先將 TGC 存在 Cookie 中,然后根據(jù) 302 的指示,攜帶上 ST 重定向到應(yīng)用1。
- 應(yīng)用1 收到瀏覽器傳來(lái)的 ST 之后,拿去 CAS Server 上校驗(yàn),去判斷用戶的登錄狀態(tài),如果用戶登錄合法,CAS Server 就會(huì)返回用戶信息給 應(yīng)用1。
- 瀏覽器再去訪問(wèn)應(yīng)用2,應(yīng)用2 發(fā)現(xiàn)用戶未登錄,重定向到 CAS Server。
- CAS Server 發(fā)現(xiàn)此時(shí)用戶實(shí)際上已經(jīng)登錄了,于是又重定向回應(yīng)用2,同時(shí)攜帶上 ST。
- 應(yīng)用2 拿著 ST 去 CAS Server 上校驗(yàn),獲取用戶的登錄信息。
- 在整個(gè)登錄過(guò)程中,瀏覽器分別和 CAS Server、應(yīng)用1、應(yīng)用2 建立了會(huì)話,其中,和 CAS Server 建立的會(huì)話稱之為全局會(huì)話,和應(yīng)用1、應(yīng)用2 建立的會(huì)話稱之為局部會(huì)話;一旦局部會(huì)話成功建立,以后用戶再去訪問(wèn)應(yīng)用1、應(yīng)用2 就不會(huì)經(jīng)過(guò) CAS Server 了。
三、CAS服務(wù)端如何部署
云程平臺(tái)對(duì)CAS 5.3.x版本無(wú)縫集成,并對(duì)CAS認(rèn)證校驗(yàn)進(jìn)行了擴(kuò)展,項(xiàng)目上請(qǐng)使用平臺(tái)提供的CAS 5.3.x運(yùn)行包。運(yùn)行CAS之前需要在數(shù)據(jù)庫(kù)先執(zhí)行平臺(tái)的腳本,CAS獲取用戶信息需訪問(wèn)平臺(tái)的SYS_USER表。
1 修改數(shù)據(jù)庫(kù)連接
打開(kāi) casWEB-INFclassesApplication.properties
修改如下配置:
#數(shù)據(jù)庫(kù)配置
spring.datasource.driver-class-name=com.MySQL.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/yuncheng2021?characterEncoding=UTF-8&useUnicode=true&useSSL=false&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.type=org.apache.commons.dbcp2.BasicDataSource
spring.jpa.database=mysql
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
2 啟動(dòng)cas
需要準(zhǔn)備Tomcat,把cas包放到tomcat/webapps目錄下,在tomcat/bin目錄下執(zhí)行startup.bat(windows)或startup.sh(linux)。
啟動(dòng)成功后訪問(wèn)cas地址,界面如下圖所示:
四、云程如何對(duì)接CAS
平臺(tái)后端CAS配置
云程平臺(tái)后端已集成CAS代碼,在yml配置文件中配置cas服務(wù)地址即可。
application.yml 進(jìn)行如下配置:
#cas單點(diǎn)登錄
cas:
prefixUrl: http://cas.example.org:8443/cas
平臺(tái)前端CAS配置
修改
public/config/bootConfig.js
VUE_APP_SSO設(shè)置為true
VUE_APP_CAS_BASE_URL配置單點(diǎn)登錄服務(wù)地址
//單點(diǎn)登錄是否開(kāi)啟
VUE_APP_SSO:true,
//單點(diǎn)登錄地址
VUE_APP_CAS_BASE_URL:"http://cas.example.org:8443/cas"