天天看點

【SpringSecurity系列(二十三)】手把手教你入門 Spring Boot + CAS 單點登入

《深入淺出Spring Security》一書已由清華大學出版社正式出版發行,感興趣的小夥伴戳這裡->->>深入淺出Spring Security,一本書學會 Spring Security。

我們來看今天的 CAS 單點登入。

在微服務以及分布式系統中,單點登入變得越來越普遍,松哥之前也有兩篇文章和大家介紹過單點登入的方案:

  • OAuth2+JWT 方案
  • @EnableOAuth2Sso 注解方案

這兩種方案中,JWT 存在一個登出登入的問題,要費點功夫解決。@EnableOAuth2Sso 注解這種方案不存在登出登入的問題,但是又不像 JWT 那麼靈活。

沒有銀彈!

在實際項目中,我們隻能根據自己的實際需求,看一看哪一種方案更适合自己,然後在此基礎上進行改造!

現在我們在 Spring Cloud Security 中使用 OAuth2+JWT 或者使用 @EnableOAuth2Sso 注解比以前要友善很多了,松哥也是最近才把項目切換到 Spring Cloud Security 技術棧上面來,在這之前,單點登入用的更多的是 CAS 單點登入。相信有不少小夥伴在公司裡可能也還是使用了 CAS 單點登入這種方案,今天松哥就來花點時間,和大家聊聊 CAS+Spring Security 實作單點登入,這種方案到底該怎麼玩。

可能會連續幾篇文章來介紹 CAS 單點登入,本文先來說說理論和登入流程。另外,由于 CAS 和 Spring Cloud OAuth2 在某些方面具有一定的相似性,是以強烈建議大家先看一看松哥的 OAuth2 系列教程,再來閱讀本文就會輕松很多(公衆号背景回複 OAuth2 有相關教程)。

本文是 Spring Security 系列第 23 篇,閱讀本系列前面的文章有助于更好的了解本文:

  1. 【SpringSecurity系列(一)】初識 Spring Security
  2. 【SpringSecurity系列(二)】Spring Security入門
  3. 【SpringSecurity系列(三)】定制表單登入
  4. 【SpringSecurity系列(四)】登入成功傳回JSON資料
  5. 【SpringSecurity系列(五)】授權入門
  6. 【SpringSecurity系列(六)】自定義登入使用者
  7. 【SpringSecurity系列(七)】通過 Spring Data Jpa 持久化使用者資料
  8. 【SpringSecurity系列(八)】使用者還能自動登入?
  9. 【SpringSecurity系列(九)】降低 RememberMe 的安全風險
  10. 在微服務項目中,Spring Security 比 Shiro 強在哪?
  11. 【SpringSecurity系列(十一)】自定義認證邏輯
  12. 【SpringSecurity系列(十二)】檢視登入詳情
  13. 【SpringSecurity系列(十三)】隻允許一台裝置線上
  14. 【SpringSecurity系列(十四)】自動踢掉上一個登入使用者
  15. 【SpringSecurity系列(十五)】請求防火牆預設已開啟
  16. 【SpringSecurity系列(十六)】會話固定攻擊與防禦
  17. 【SpringSecurity系列(十七)】Spring Security 如何處理 Session 共享
  18. 【SpringSecurity系列(十八)】SpringBoot 如何防禦 CSRF 攻擊?
  19. 【SpringSecurity系列(十九)】Spring Security 中 CSRF 防禦源碼解析
  20. 【SpringSecurity系列(二十)】密碼加密的兩種姿勢
  21. 【SpringSecurity系列(二十一)】Spring Security 怎麼學?為什麼一定需要系統學習?
  22. 【SpringSecurity系列(二十二)】Spring Security 兩種資源放行政策,千萬别用錯了!

1.什麼是 CAS

CAS 全稱叫做中央認證服務,英文是 Central Authentication Service。

這是由耶魯大學發起的一個開源項目,目的是幫助 Web 應用系統建構一種可靠的單點登入解決方案,從目前企業實際項目來看,CAS 還是非常受歡迎的一種單點登入解決方案。

1.1 CAS 架構

CAS 分為兩部分:

  • 一個是 CAS Server,這是單點驗證服務,作用類似于我們OAuth2+JWT 方案中的授權伺服器,用來校驗使用者名/密碼等,一般來說都是獨立部署。
  • 另一個則是 CAS Client,相當于就是一個一個的(微)服務。

我們來看 CAS 的官方給出的一個架構圖:

【SpringSecurity系列(二十三)】手把手教你入門 Spring Boot + CAS 單點登入

可以看到,使用者通路的是 CAS Clients,CAS Clients 和 CAS Server 之間的通信支援多種協定,CAS Server 處理具體的認證事宜,CAS Server 對資料源的支援也非常多樣化。

CAS Client 支援的平台有:

  • 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 支援的通信協定有:

  • CAS (versions 1, 2, and 3)
  • SAML 1.1 and 2
  • OpenID Connect
  • OpenID
  • OAuth 2.0
  • WS Federation

從圖中也可以看出 CAS 支援多種不同的認證機制,具體有:

  • JAAS
  • LDAP
  • RDBMS
  • SPNEGO
  • ...

1.2 三個概念

在 CAS 的整個登入過程中,有三個重要的概念,這裡我先來和大家捋一捋。

  1. TGT:TGT 全稱叫做 Ticket Granting Ticket,這個相當于我們平時所見到的 HttpSession 的作用,使用者登入成功後,使用者的基本資訊,如使用者名、登入有效期等資訊,都将存儲在此。
  2. TGC:TGC 全稱叫做 Ticket Granting Cookie,TGC 以 Cookie 的形式儲存在浏覽器中,根據 TGC 可以幫助使用者找到對應的 TGT,是以這個 TGC 有點類似與會話 ID。
  3. ST:ST 全稱是 Service Ticket,這是 CAS Sever 通過 TGT 給使用者發放的一張票據,使用者在通路其他服務時,發現沒有 Cookie 或者 ST ,那麼就會 302 到 CAS Server 擷取 ST,然後會攜帶着 ST 302 回來,CAS Client 則通過 ST 去 CAS Server 上擷取使用者的登入狀态。

2.CAS 登入流程

接下來我們通過一張官方給出的流程圖來看下 CAS 登入過程是什麼樣子的!

【SpringSecurity系列(二十三)】手把手教你入門 Spring Boot + CAS 單點登入

這張圖其實畫的比較清楚了,我再用文字和大家解釋下:

術語:應用1、應用2 分别表示被保護的應用。

  1. 使用者通過浏覽器通路應用1,應用1 發現使用者沒有登入,于是傳回 302,并且攜帶上一個 service 參數,讓使用者去 CAS Server 上登入。
  2. 浏覽器自動重定向到 CAS Server 上,CAS Server 擷取使用者 Cookie 中攜帶的 TGC,去校驗使用者是否已經登入,如果已經登入,則完成身份校驗(此時 CAS Server 可以根據使用者的 TGC 找到 TGT,進而擷取使用者的資訊);如果未登入,則重定向到 CAS Server 的登入頁面,使用者輸入使用者名/密碼,CAS Server 會生成 TGT,并且根據 TGT 簽發一個 ST,再将 TGC 放在使用者的 Cookie 中,完成身份校驗。
  3. CAS Server 完成身份校驗之後,會将 ST 拼接在 service 中,傳回 302,浏覽器将首先将 TGC 存在 Cookie 中,然後根據 302 的訓示,攜帶上 ST 重定向到應用1。
  4. 應用1 收到浏覽器傳來的 ST 之後,拿去 CAS Server 上校驗,去判斷使用者的登入狀态,如果使用者登入合法,CAS Server 就會傳回使用者資訊給 應用1。
  5. 浏覽器再去通路應用2,應用2 發現使用者未登入,重定向到 CAS Server。
  6. CAS Server 發現此時使用者實際上已經登入了,于是又重定向回應用2,同時攜帶上 ST。
  7. 應用2 拿着 ST 去 CAS Server 上校驗,擷取使用者的登入資訊。

在整個登入過程中,浏覽器分别和 CAS Server、應用1、應用2 建立了會話,其中,和 CAS Server 建立的會話稱之為全局會話,和應用1、應用2 建立的會話稱之為局部會話;一旦局部會話成功建立,以後使用者再去通路應用1、應用2 就不會經過 CAS Server 了。

3.CAS Server 搭建

說了這麼多,來點實際的。

由于整個 CAS 單點登入做起來還比較麻煩,我們一步一步來,今天我先來教大家把 CAS Server 搭建起來。

3.1 版本選擇

目前最新的 CAS Server 是 6.x,這個是基于 gradle 來建構的,考慮到很多小夥伴可能不熟悉 gradle 操作,是以這裡我選擇 5.3 的版本,該版本基于大家熟悉的 maven 來建構。

官方為我們提供了建構 CAS Server 的模版,位址是:https://github.com/apereo/cas-overlay-template。

我們在分支中選擇 5.3 版本下載下傳:

【SpringSecurity系列(二十三)】手把手教你入門 Spring Boot + CAS 單點登入

或者直接 clone 下來,然後切換到 5.3 這個分支也可以。這個應該就不用我教大家了吧,相信小夥伴們都能自己搞定。

3.2 HTTPS 證書

CAS Server 從版本 4 開始,要使用 HTTPS 通信,是以我們得提前準備 HTTPS 證書。公司裡的項目的話,需要購買 HTTPS 證書,自己玩的話也可以從雲服務廠商那裡申請到免費的 HTTPS 證書。

現在我們在本地測試,直接利用 JDK 自帶的 keytool 工具,自己生成一個 HTTPS 證書即可。

生成指令如下:

keytool -genkey -alias casserver -keyalg RSA -keystore ./keystore
           

複制

  • -alias 表示生成的證書别名
  • -keyalg 表示生成證書使用的算法
  • -keystore 表示生成證書的存放位置

證書在執行的時候,需要給一個密鑰庫密碼,這個大家随意給出即可,但是給出了多少要自己記着。另外,在

What is your first and last name?

選項中,需要填入 CAS Server 的域名,這點切記:

【SpringSecurity系列(二十三)】手把手教你入門 Spring Boot + CAS 單點登入

如此之後,我們的 HTTPS 證書就有了,雖然這個證書不被各大廠商認可,但是自己做練習夠用了。

3.3 配置并啟動

接下來進行配置。

我們在下載下傳的 cas-overlay-template 項目中,建立 src/main/resources 目錄,并将 overlays/org.apereo.cas.cas-server-webapp-tomcat-5.3.14/WEB-INF/classes/application.properties 檔案和剛剛生成的 keystore 檔案拷貝進來:

【SpringSecurity系列(二十三)】手把手教你入門 Spring Boot + CAS 單點登入

然後修改 application.properties ,主要配置一下 keystore 的位置和密鑰,如下:

server.ssl.key-store=classpath:keystore
server.ssl.key-store-password=111111
server.ssl.key-password=111111
           

複制

配置完成後,在項目根目錄下執行如下指令啟動項目:

./build.sh bootrun

根據個人網速,第一次啟動可能會非常漫長,耐心等待即可。

啟動過程中,也可能會報錯,但是不用管,如果看到 ready 圖示,就表示啟動成功了:

【SpringSecurity系列(二十三)】手把手教你入門 Spring Boot + CAS 單點登入

3.4 測試

啟動成功後,浏覽器輸入 https://cas.javaboy.org:8443/cas/login 就可以進入登入頁面了(注意是 https 哦):

【SpringSecurity系列(二十三)】手把手教你入門 Spring Boot + CAS 單點登入

預設的使用者名是 casuser,密碼是 Mellon,輸入使用者名密碼就可以登入了。

【SpringSecurity系列(二十三)】手把手教你入門 Spring Boot + CAS 單點登入

預設的使用者名/密碼也可以在 application.properties 檔案中修改,該檔案的最後一行:

cas.authn.accept.users=casuser::Mellon
           

複制

修改完後,重新開機項目即可生效。

4.小結

今天主要和小夥伴聊一下 CAS 的基本概念,然後我們順手搭建一個 CAS Server 出來,感興趣的小夥伴可以動手試一試哦~,下篇文章我們來看如何用 Spring Boot 開發 CAS 用戶端~

好啦,如果小夥伴們覺得有收獲,記得點個在看鼓勵下松哥哦~