目錄如下:
為什么需要自定義授權類型?
前面介紹OAuth2.0的基礎知識點時介紹過支持的4種授權類型,分別如下:
- 授權碼模式
- 簡化模式
- 客戶端模式
- 密碼模式
實際生產中上述四種授權類型根本不夠用,比如常見的授權類型如下:
- 微信認證
- QQ認證
- 手機號+驗證碼認證
- 圖形驗證碼認證
- 郵箱認證
因此我們必須懂得OAuth2.0如何自定義授權類型,這也是本篇文章的重點。
實現思路
Spring Security 定制授權類型其實很簡單,主要是掌握其中的思路,下面是密碼模式的授權流程,如下圖:
根據上述流程圖可以跟著源碼進去看看,不難發現有幾個如下重要點:
- 每種授權類型都對應一個實現類TokenGranter,其中定義著授權類型。
- 所有 TokenGranter 實現類都通過 CompositeTokenGranter 中的tokenGranters 集合存起來。
- 然后通過判斷 grantType 參數來定位具體使用那個 TokenGranter實現類來處理授權。
- 每種授權方式都對應一個AuthenticationProvider。
- TokenGranter 類會 new 一個 AuthenticationToken實現類,如 UsernamePasswordAuthenticationToken 傳給 ProviderManager類。
因此想要自定義一個授權類型,必須構建自己的TokenGranter、AuthenticationProvider、AuthenticationToken。
代碼實現
下面就以手機號+密碼的登錄方式定義一個類型:mobile_pwd,剩下的自己照葫蘆畫瓢。
1、自定義UserDetailService
這個和密碼授權類型類似,要實現一個方法從數據庫中根據手機號查詢用戶的詳細信息。
定義一個SmsCodeUserDetailService接口如下:
主要就是一個 loadUserByMobile() 方法,實現類如下:
2、自定義AuthenticationToken
類似于密碼模式的中UsernamePasswordAuthenticationToken,自定義一個MobilePasswordAuthenticationToken封裝手機號和密碼,如下:
3、自定義TokenGranter
每種授權類型都對應一種TokenGranter,其中會定義授權類型的名稱,比如密碼模式的ResourceOwnerPasswordTokenGranter,其中的GRANT_TYPE為password。
自定義一個MobilePwdGranter,照葫蘆畫瓢,模仿著改改,代碼如下:
4、自定義AuthenticationProvider
這個類就是真正的處理類,經過TokenGranter后,會找到對應的AuthenticationProvider,然后取出參數從數據庫(UserDetailService)中查詢對應的信息進行匹配。
自定義MobilePasswordAuthenticationProvider,代碼如下:
5、將自定義的MobilePasswordAuthenticationProvider注入IOC容器
這里必須將自定義的MobilePasswordAuthenticationProvider注入到IOC容器,如果不注入,會報找不到能處理的AuthenticationProvider這個異常。
新建SmsCodeSecurityConfig,代碼如下:
注意:由于使用的外部配置,因此必須在全局配置中指定。
6、Security的全局配置指定SmsCodeSecurityConfig
由于是分開配置,因此必須在全局配置中指定才會生效,代碼如下:
7、加到CompositeTokenGranter集合中
需要將自定義的授權類型加到集合CompositeTokenGranter中,此處需要修改認證中心的配置類(AuthorizationServerConfig)中的代碼,如下:
8、oauth_client_details表中添加授權類型
oauth_client_details這個表是存儲客戶端的詳細信息的,需要在對應的客戶端資源那一行中的authorized_grant_types這個字段中添加自定義的授權類型,多個用逗號分隔。
測試
經過上述的步驟已經配置完成,下面來測試,啟動服務,請求如下:
源碼獲取
授權類型主要是針對 認證中心(oauth2-cloud-auth-server) 的改動,改動的目錄如下:
陳某直接在之前網關整合Spring Security的源碼上更改了一版。
原文地址:https://mp.weixin.qq.com/s/4XS3cIFR0UBtCW4TSKtEKg