首頁 > 要聞 > > 正文

SpringSecurity+OAuth2.0的改造

2023-07-03 16:33:00    來源:Java架構(gòu)學(xué)習(xí)指南

背景

最近,公司的標(biāo)準(zhǔn)B端產(chǎn)品,遇到了兩個(gè)客戶的定制化需求:

1.A客戶公司要求產(chǎn)品需要集成他們的單點(diǎn)登錄,客戶還提出來,他們今年沒有這方面的預(yù)算,要求自己在我們的源碼基礎(chǔ)上二開。


【資料圖】

2.B客戶公司說他們集團(tuán)有要求,產(chǎn)品都需要集成雙因子認(rèn)證登錄的功能,同樣他們登錄也要求接入他們的用戶中心。

我們的產(chǎn)品登錄認(rèn)證是基于# SpringSecurity+OAuth2.0。

看起來登錄認(rèn)證,接入客戶的用戶中心這個(gè)場景在安全的大背景下,是一個(gè)普遍的需求場景了,遂納入了迭代版本,同時(shí)考慮到后續(xù)版本升級(jí)及維護(hù)成本,進(jìn)行統(tǒng)一的設(shè)計(jì),留好接口,做到良好的代碼隔離及擴(kuò)展。

我的工作思路

1.接到這種需求,首先第一考慮的當(dāng)然是搜索,github上找現(xiàn)成方案,hahah,沒錯(cuò),面相搜索的編程原則不能丟,用經(jīng)過別人實(shí)踐的方案,或者是這個(gè)模塊的通用解決方案,不用自己想歪招~

2.當(dāng)我查了半天,發(fā)現(xiàn)S# SpringSecurity+OAuth2.0原理解釋的文章一大堆,但是真正關(guān)于這兩個(gè)需求相關(guān)的方案很少,僅有的幾篇要么寫的不清楚,要么不是我想要的,無奈還是得自己調(diào)研,做方案設(shè)計(jì)。

tips:
SpringSecurity+OAuth2.0我只是以前作為學(xué)習(xí)了解過,最多寫過demo,之前沒有負(fù)責(zé)過登錄模塊,并且好幾年了,也只是了解寫概念和基本流程,并不足以支撐我進(jìn)行方案設(shè)計(jì)和基SpringSecurity+OAuth2.0的改造。那就只能重新回顧原理去了。

這里為什么說不足以支撐我做方案設(shè)計(jì)呢,我個(gè)人認(rèn)為SpringSecurity+OAuth2.0的方案,框架封閉程度太高了。

幾個(gè)概念

1.OAuth2.0

2.SpringSecurity+OAuth2.0

3.單點(diǎn)登錄

這幾個(gè)概念比較普遍了,不知道的也可以網(wǎng)上搜一下,都寫的比較透徹了。

4.雙因子登錄可能有些人不太清楚,這里重點(diǎn)說一下:

其實(shí)這也不是新概念了,早年的銀行U盾+用戶名密碼也是雙因子的一種。 就舉個(gè)現(xiàn)在C端常用的例子吧:

正常你可能用戶名+密碼就完成了登錄,但是當(dāng)你某一天去外地出差,在輸入用戶名密碼后,跳轉(zhuǎn)到了另一個(gè)頁面要求你用短信驗(yàn)證碼做二次認(rèn)證,大概就是這么個(gè)場景。概括的說:在系統(tǒng)基于大數(shù)據(jù)識(shí)別到風(fēng)險(xiǎn)或者異常行為,開啟第二種登錄認(rèn)證方式。

談?wù)勎业脑O(shè)計(jì)方案

根據(jù)需求背景,那我希望的是:

1.三方登錄集成:
SpringSecurity的用戶名密碼認(rèn)證,可以基于策略模式,來實(shí)現(xiàn)。(基于本地的密碼認(rèn)證策略,三方接口接入的)

2.雙因子登錄:
在用戶請求登錄時(shí),增加預(yù)校驗(yàn)接口,先校驗(yàn)是否需要雙因子認(rèn)證,如果不需要,則直接加載密碼授權(quán)模式辦法token,如果需要,則先不能辦發(fā)token,再增加一個(gè)自定義的grant_type,來進(jìn)行短信驗(yàn)證碼的授權(quán)模式,并頒發(fā)token。

目標(biāo)出發(fā),再看oauth2.0的工作及實(shí)現(xiàn)原理

由于原來的實(shí)現(xiàn)是授權(quán)碼模式(authorization code),那我們來看他的工作流程及原理:
我們畫出他的時(shí)序圖:

集成三方登錄

從上述時(shí)序圖來看,這個(gè)需求,我們關(guān)鍵是關(guān)注下述這個(gè)地方:

他的密碼認(rèn)證的核心邏輯在DaoAuthenticationProvider類的additionalAuthenticationChecks方法

接下來,我決定重寫該類的additionalAuthenticationChecks方法,這樣就能滿足我的想法,同時(shí)原來的代碼結(jié)構(gòu)不用破壞,權(quán)限等的加載邏輯也都不用動(dòng)。

我的具體實(shí)現(xiàn)方案

自定義重寫additionalAuthenticationChecks方法

基于策略模式實(shí)現(xiàn)不用認(rèn)證方式的加載

加載自己的CustomLoginAuthProvider

SecurityConfigurer中加入自己的configure

tips: 這里有個(gè)小坑,mark一下,我還查了好就:

雙因子登錄

還是根據(jù)調(diào)用的時(shí)序圖來看:

關(guān)于授權(quán)類型 grant_type 的解析

1.每種 grant_type 都會(huì)有一個(gè)對應(yīng)的 TokenGranter 實(shí)現(xiàn)類。
2.所有 TokenGranter 實(shí)現(xiàn)類都通過 CompositeTokenGranter 中的 tokenGranters 集合存起來。
3.然后通過判斷 grantType 參數(shù)來定位具體使用那個(gè) TokenGranter 實(shí)現(xiàn)類來處理授權(quán)。

關(guān)于授權(quán)登錄邏輯

1.每種 授權(quán)方式 都會(huì)有一個(gè)對應(yīng)的 AuthenticationProvider 實(shí)現(xiàn)類來實(shí)現(xiàn)。
2.所有 AuthenticationProvider 實(shí)現(xiàn)類都通過 ProviderManager 中的 providers 集合存起來。
3.TokenGranter 類會(huì) new 一個(gè) AuthenticationToken 實(shí)現(xiàn)類,如 UsernamePasswordAuthenticationToken 傳給 ProviderManager 類。
4.而 ProviderManager 則通過 AuthenticationToken 來判斷具體使用那個(gè)AuthenticationProvider 實(shí)現(xiàn)類來處理授權(quán)。
5.具體的登錄邏輯由 AuthenticationProvider 實(shí)現(xiàn)類來實(shí)現(xiàn),如 DaoAuthenticationProvider。

基于以上我這里實(shí)現(xiàn)了單獨(dú)的SmsGranter

關(guān)鍵詞:

上一篇:大力神杯真的給冠軍保存四年嗎是真的嗎(大力神杯真的給冠軍保存四年嗎)
下一篇:最后一頁

熱點(diǎn)話題

熱點(diǎn)推薦

頭條

?