西安大型網(wǎng)站制作什么網(wǎng)站可以發(fā)布廣告
之所以想寫這一系列,是因?yàn)橹肮ぷ鬟^程中使用Spring Security OAuth2搭建了網(wǎng)關(guān)和授權(quán)服務(wù)器,但當(dāng)時基于spring-boot 2.3.x,其默認(rèn)的Spring Security是5.3.x。之后新項(xiàng)目升級到了spring-boot 3.3.0,結(jié)果一看Spring Security也升級為6.3.0。無論是Spring Security的風(fēng)格和以及OAuth2都做了較大改動,里面甚至將授權(quán)服務(wù)器模塊都移除了,導(dǎo)致在配置同樣功能時,花費(fèi)了些時間研究新版本的底層原理,這里將一些學(xué)習(xí)經(jīng)驗(yàn)分享給大家。
注意:由于框架不同版本改造會有些使用的不同,因此本次系列中使用基本框架是 spring-boo-3.3.0(默認(rèn)引入的Spring Security是6.3.0),JDK版本使用的是19,本系列OAuth2的代碼采用Spring Security6.3.0框架,所有代碼都在oauth2-study項(xiàng)目上:https://github.com/forever1986/oauth2-study.git
目錄
- 1 關(guān)鍵的類
- 1.1 Authentication
- 1.2 AuthenticationConverter
- 1.3 AuthenticationProvider
- 2 授權(quán)碼模式的底層原理
- 3 授權(quán)碼模式整體流程圖
- 4 關(guān)鍵的Filter過濾器
- 4.1 OAuth2AuthorizationEndpointFilter(授權(quán)碼code請求處理)
- 4.2 OAuth2TokenEndpointFilter(返回token)
- 4.3 OAuth2ClientAuthenticationFilter(客戶端認(rèn)證)
前面我們了解授權(quán)服務(wù)器的實(shí)現(xiàn)以及自定義客戶端、自定義授權(quán)頁面,也窺探了其中部分原理。這一章,我們通過授權(quán)碼模式下,分析一下Spring Authrization Server的基本原理,同時對其中一些關(guān)鍵的Filter過濾器列出來,對后續(xù)實(shí)現(xiàn)功能會有幫助。我們知道Spring Authrization Server也是基于Spring Security 6基礎(chǔ)上實(shí)現(xiàn)的,因此其關(guān)鍵功能都在其過濾器上面。下圖紅色框框的是Spring Authrization Server新增的過濾器,我們挑一些關(guān)鍵的解釋一下
1 關(guān)鍵的類
在介紹關(guān)鍵的過濾器之前,有幾個類需要先說明一下其作用,對后面閱讀源碼有很好的理解。
1.1 Authentication
Authentication其實(shí)是Spring Security的接口,主要就是封裝認(rèn)證信息,用于上下文傳輸,而在Spring Authrization Server中,有幾個實(shí)現(xiàn)類比較重要:
- OAuth2AuthorizationCodeRequestAuthenticationToken:在授權(quán)碼模式下,獲取授權(quán)碼時候封裝的信息
- OAuth2AuthorizationConsentAuthenticationToken:在授權(quán)碼模式下,跳轉(zhuǎn)授權(quán)界面時,封裝所需的信息
- OAuth2AuthorizationCodeAuthenticationToken:在請求token時,封裝所需的信息
- OAuth2TokenExchangeAuthenticationToken:在交換token請求下,封裝所需的信息
- OAuth2RefreshTokenAuthenticationToken:在刷新token請求下,封裝所需的信息
1.2 AuthenticationConverter
AuthenticationConverter是一個request參數(shù)轉(zhuǎn)換為Authentication的一個轉(zhuǎn)換器,其中有幾個實(shí)現(xiàn)類比較重要
- OAuth2AuthorizationCodeRequestAuthenticationConverter:在請求授權(quán)碼時,將request的參數(shù)都封裝為Authentication
- OAuth2AuthorizationConsentAuthenticationConverter:在請求授權(quán)碼時,點(diǎn)擊授權(quán)頁面的確認(rèn)后,將request的參數(shù)都封裝為Authentication
- OAuth2AuthorizationCodeAuthenticationConverter:在請求token時,將request的參數(shù)都封裝為Authentication
- OAuth2TokenExchangeAuthenticationConverter:在交換token時,將request的參數(shù)都封裝為Authentication
- OAuth2RefreshTokenAuthenticationConverter:在刷新token時,將request的參數(shù)都封裝為Authentication
1.3 AuthenticationProvider
AuthenticationProvider本身是Spring Security的接口,主要是用于驗(yàn)證結(jié)果,比如用戶名密碼登錄等,這里Spring Authrization Server通過實(shí)現(xiàn)不同的AuthenticationProvider做不同驗(yàn)證,以下幾個實(shí)現(xiàn)類比較重要:
- OAuth2AuthorizationCodeRequestAuthenticationProvider:主要用于授權(quán)碼模式下,客戶端的驗(yàn)證
- OAuth2AuthorizationConsentAuthenticationProvider:授權(quán)頁面點(diǎn)擊確認(rèn)之后,客戶端驗(yàn)證
- OAuth2AuthorizationCodeAuthenticationProvider:獲取token接口時,客戶端驗(yàn)證
- OAuth2TokenExchangeAuthenticationProvider:交換token接口時,客戶端驗(yàn)證
- OAuth2RefreshTokenAuthenticationProvider:請求刷新token接口時,客戶端驗(yàn)證
2 授權(quán)碼模式的底層原理
1)我們從《系列之四-客戶端–oauth2-client底層原理》中可知,客戶端會訪問/oauth2/authorize接口,這時候會有先到達(dá)OAuth2AuthorizationEndpointFilter過濾器,但是由于未登錄,因此會被認(rèn)定沒有權(quán)限,不做處理,繼續(xù)走過濾器鏈。
2)接著,請求會接著跳轉(zhuǎn)到AuthorizationFilter過濾器(這是Spring Security的過濾器,做認(rèn)證判斷的),這時候會報AccessDeniedException異常,并由LoginUrlAuthenticationEntryPoint處理,跳轉(zhuǎn)到Spring Security的登錄界面
3)出現(xiàn)登錄界面,進(jìn)行登錄之后,會繼續(xù)請求/oauth2/authorize接口,這時候會被OAuth2AuthorizationEndpointFilter攔截,我們再看看OAuth2AuthorizationEndpointFilter的doFilterInternal方法
- 第一步:判斷URI是否符合/oauth2/authorize
- 第二步:判斷客戶端信息是否符合要求
- 第三步:判斷是否已經(jīng)登錄,沒有登錄,則由其它過濾器跳轉(zhuǎn)到登錄界面
- 第四步:判斷是否已經(jīng)授權(quán),沒有授權(quán)則跳轉(zhuǎn)到登錄界面
- 第五步:前面4步都沒問題,則返回授權(quán)的code
下面我們將詳細(xì)的源碼調(diào)用過程列出來:
4)返回授權(quán)碼給客戶的之后,客戶端會繼續(xù)請求http://oauth-server:9000/oauth2/token獲取token,而授權(quán)服務(wù)器的token由OAuth2TokenEndpointFilter過濾器處理
OAuth2TokenEndpointFilter是攔截"/oauth2/token"獲取token請求,通過將request的參數(shù)封裝為OAuth2AuthorizationCodeAuthenticationToken,然后調(diào)用OAuth2AuthorizationCodeAuthenticationProvider驗(yàn)證并生成token,通過后調(diào)用OAuth2AccessTokenResponseAuthenticationSuccessHandler返回token
3 授權(quán)碼模式整體流程圖
4 關(guān)鍵的Filter過濾器
從上面的整體流程,我們知道一些關(guān)鍵的Filter過濾器,這里羅列出來,后續(xù)講解授權(quán)碼其它功能時,會經(jīng)常提到。
4.1 OAuth2AuthorizationEndpointFilter(授權(quán)碼code請求處理)
在《系列之五 - 授權(quán)服務(wù)器–開篇》和本系列中分析過該過濾器。該過濾器專門處理/oauth2/authorize接口,在授權(quán)碼模式下,該接口就是用于跳轉(zhuǎn)到授權(quán)界面以及返回授權(quán)碼的作用
4.2 OAuth2TokenEndpointFilter(返回token)
OAuth2TokenEndpointFilter是攔截"/oauth2/token"獲取token請求,通過將request的參數(shù)封裝為OAuth2AuthorizationCodeAuthenticationToken,然后調(diào)用OAuth2AuthorizationCodeAuthenticationProvider驗(yàn)證并生成token,通過后調(diào)用OAuth2AccessTokenResponseAuthenticationSuccessHandler返回token
4.3 OAuth2ClientAuthenticationFilter(客戶端認(rèn)證)
OAuth2ClientAuthenticationFilter主要是用于客戶端認(rèn)證,包括通過client_secret_basic、client_secret_post、client_secret_jwt、private_key_jwt、none、tls_client_auth和self_signed_tls_client_auth等不同認(rèn)證方式。因此增加改攔截器用于客戶端認(rèn)證,其邏輯流程和OAuth2AuthorizationEndpointFilter前半部分有很大的相似,都是使用AuthenticationConverter轉(zhuǎn)換參數(shù),然后AuthenticationProvider進(jìn)行驗(yàn)證。這塊具體會在《系列之十五 - 高級特性–客戶端認(rèn)證方式》中詳細(xì)說明。
結(jié)語:本章我們對Spring Authrization Server如何實(shí)現(xiàn)授權(quán)碼模式以及自定義客戶端信息進(jìn)行源碼解析,并了解了幾個關(guān)鍵的Filter過濾器。有了這個基礎(chǔ),對接下來我們實(shí)現(xiàn)更為高級的授權(quán)服務(wù)器功能,并了解實(shí)現(xiàn)原理就變得更為容易。