手把手教你入門(mén) Spring Boot + CAS 單點(diǎn)登錄
1.什么是 CAS
CAS 全稱叫做中央認(rèn)證服務(wù),英文是 Central Authentication Service。
這是由耶魯大學(xué)發(fā)起的一個(gè)開(kāi)源項(xiàng)目,目的是幫助 Web 應(yīng)用系統(tǒng)構(gòu)建一種可靠的單點(diǎn)登錄解決方案,從目前企業(yè)實(shí)際項(xiàng)目來(lái)看,CAS 還是非常受歡迎的一種單點(diǎn)登錄解決方案。
1.1 CAS 架構(gòu)
CAS 分為兩部分:
- 一個(gè)是 CAS Server,這是單點(diǎn)驗(yàn)證服務(wù),作用類(lèi)似于我們OAuth2+JWT 方案中的授權(quán)服務(wù)器,用來(lái)校驗(yàn)用戶名/密碼等,一般來(lái)說(shuō)都是獨(dú)立部署。
- 另一個(gè)則是 CAS Client,相當(dāng)于就是一個(gè)一個(gè)的(微)服務(wù)。
我們來(lái)看 CAS 的官方給出的一個(gè)架構(gòu)圖:
可以看到,用戶訪問(wèn)的是 CAS Clients,CAS Clients 和 CAS Server 之間的通信支持多種協(xié)議,CAS Server 處理具體的認(rèn)證事宜,CAS Server 對(duì)數(shù)據(jù)源的支持也非常多樣化。
CAS Client 支持的平臺(tái)有:
- Apache httpd Server (mod_auth_cas module)
- Java (Java CAS Client)
- .NET (.NET CAS Client)
- PHP (phpCAS)
- Perl (PerlCAS)
- Python (pycas)
- Ruby (rubycas-client)
CAS 支持的通信協(xié)議有:
- CAS (versions 1, 2, and 3)
- SAML 1.1 and 2
- OpenID Connect
- OpenID
- OAuth 2.0
- WS Federation
從圖中也可以看出 CAS 支持多種不同的認(rèn)證機(jī)制,具體有:
- JAAS
- LDAP
- RDBMS
- SPNEGO
...
1.2 三個(gè)概念
在 CAS 的整個(gè)登錄過(guò)程中,有三個(gè)重要的概念,這里我先來(lái)和大家捋一捋。
- 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)類(lèi)似與會(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)。
2.CAS 登錄流程
接下來(lái)我們通過(guò)一張官方給出的流程圖來(lái)看下 CAS 登錄過(guò)程是什么樣子的!
這張圖其實(shí)畫(huà)的比較清楚了,我再用文字和大家解釋下:
術(shù)語(yǔ):應(yīng)用1、應(yīng)用2 分別表示被保護(hù)的應(yīng)用。
- 用戶通過(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 了。
3.CAS Server 搭建
說(shuō)了這么多,來(lái)點(diǎn)實(shí)際的。
由于整個(gè) CAS 單點(diǎn)登錄做起來(lái)還比較麻煩,我們一步一步來(lái),今天我先來(lái)教大家把 CAS Server 搭建起來(lái)。
3.1 版本選擇
目前最新的 CAS Server 是 6.x,這個(gè)是基于 gradle 來(lái)構(gòu)建的,考慮到很多小伙伴可能不熟悉 gradle 操作,因此這里我選擇 5.3 的版本,該版本基于大家熟悉的 maven 來(lái)構(gòu)建。
官方為我們提供了構(gòu)建 CAS Server 的模版,地址是:https://github.com/apereo/cas-overlay-template。
我們?cè)诜种е羞x擇 5.3 版本下載:
或者直接 clone 下來(lái),然后切換到 5.3 這個(gè)分支也可以。這個(gè)應(yīng)該就不用我教大家了吧,相信小伙伴們都能自己搞定。
3.2 HTTPS 證書(shū)
CAS Server 從版本 4 開(kāi)始,要使用 HTTPS 通信,所以我們得提前準(zhǔn)備 HTTPS 證書(shū)。公司里的項(xiàng)目的話,需要購(gòu)買(mǎi) HTTPS 證書(shū),自己玩的話也可以從云服務(wù)廠商那里申請(qǐng)到免費(fèi)的 HTTPS 證書(shū)。
現(xiàn)在我們?cè)诒镜販y(cè)試,直接利用 JDK 自帶的 keytool 工具,自己生成一個(gè) HTTPS 證書(shū)即可。
生成命令如下:
- keytool -genkey -alias casserver -keyalg RSA -keystore ./keystore
- -alias 表示生成的證書(shū)別名
- -keyalg 表示生成證書(shū)使用的算法
- -keystore 表示生成證書(shū)的存放位置
證書(shū)在執(zhí)行的時(shí)候,需要給一個(gè)密鑰庫(kù)口令,這個(gè)大家隨意給出即可,但是給出了多少要自己記著。另外,在 What is your first and last name? 選項(xiàng)中,需要填入 CAS Server 的域名,這點(diǎn)切記:
如此之后,我們的 HTTPS 證書(shū)就有了,雖然這個(gè)證書(shū)不被各大廠商認(rèn)可,但是自己做練習(xí)夠用了。
3.3 配置并啟動(dòng)
接下來(lái)進(jìn)行配置。
我們?cè)谙螺d的 cas-overlay-template 項(xiàng)目中,新建 src/main/resources 目錄,并將 overlays/org.apereo.cas.cas-server-webapp-tomcat-5.3.14/WEB-INF/classes/application.properties 文件和剛剛生成的 keystore 文件拷貝進(jìn)來(lái):
然后修改 application.properties ,主要配置一下 keystore 的位置和密鑰,如下:
- server.ssl.key-store=classpath:keystore
- server.ssl.key-store-password=111111
- server.ssl.key-password=111111
配置完成后,在項(xiàng)目根目錄下執(zhí)行如下命令啟動(dòng)項(xiàng)目:
./build.sh bootrun
根據(jù)個(gè)人網(wǎng)速,第一次啟動(dòng)可能會(huì)非常漫長(zhǎng),耐心等待即可。
啟動(dòng)過(guò)程中,也可能會(huì)報(bào)錯(cuò),但是不用管,如果看到 ready 圖標(biāo),就表示啟動(dòng)成功了:
3.4 測(cè)試
啟動(dòng)成功后,瀏覽器輸入 https://cas.javaboy.org:8443/cas/login 就可以進(jìn)入登錄頁(yè)面了(注意是 https 哦):
默認(rèn)的用戶名是 casuser,密碼是 Mellon,輸入用戶名密碼就可以登錄了。
默認(rèn)的用戶名/密碼也可以在 application.properties 文件中修改,該文件的最后一行:
- cas.authn.accept.users=casuser::Mellon
修改完后,重啟項(xiàng)目即可生效。
4.小結(jié)
今天主要和小伙伴聊一下 CAS 的基本概念,然后我們順手搭建一個(gè) CAS Server 出來(lái),感興趣的小伙伴可以動(dòng)手試一試哦~,下篇文章我們來(lái)看如何用 Spring Boot 開(kāi)發(fā) CAS 客戶端~
本文轉(zhuǎn)載自微信公眾號(hào)「江南一點(diǎn)雨」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系江南一點(diǎn)雨公眾號(hào)。