Spring-security-oauth2 與 Spring-security

spring security 認(rèn)證流程:

1. 當(dāng)?shù)卿洉r(shí),請(qǐng)求會(huì)被UsernamePasswordAuthenticationFilter 攔截, 獲取用戶(hù)名和密碼,封裝成UsernamePasswordAuthenticationToken,并交給AuthenticationManager(認(rèn)證核心接口)去認(rèn)證;

2. ProviderManager 是AuthenticationManager接口的實(shí)現(xiàn)類(lèi),也就是驗(yàn)證UsernamePasswordAuthenticationToken時(shí)交給它來(lái)處理。

3. ProviderManager 的authenticate(authentication) 方法,是驗(yàn)證UsernamePasswordAuthenticationToken的核心方法;從源碼可以得知:ProviderManager? 有 一個(gè)屬性為:List providers; 從名稱(chēng)就可以看出,是一個(gè)認(rèn)證器的集合;所以authenticate(authentication)方法的主要邏輯就是遍歷providers, support(UsernamePasswordAuthenticationToken)的AuthenticationProvider 會(huì)去做相應(yīng)的認(rèn)證;

AuthenticationProvider 認(rèn)證用戶(hù)三步走原則:

(1)獲取用戶(hù)信息

(2)檢查用戶(hù)“是否被禁用”,“是否被鎖定”,“是否過(guò)期”

(3)校驗(yàn)用戶(hù)名和密碼

4. 通過(guò)驗(yàn)證返回Authentication

5. 通過(guò)驗(yàn)證返回Authentication

6. 通過(guò)驗(yàn)證返回Authentication到 AbstractAuthenticationProcessingFilter

7. successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) 發(fā)布登錄成功;

主要邏輯為:

(1)Authentication保存到SecurityContext中; 源碼:SecurityContextHolder.getContext().setAuthentication(authResult);

(2)如果配合記住密碼,則會(huì)記住密碼;??? 源碼:this.rememberMeServices.loginSuccess(request, response, authResult);

?(3)? 請(qǐng)求之前未登錄狀態(tài)下請(qǐng)求的網(wǎng)址;??? 源碼:this.successHandler.onAuthenticationSuccess(request, response, authResult)

說(shuō)明:SecurityContextHolder.getContext().setAuthentication(authResult),底層源碼是使用new ThreadLocal() 存儲(chǔ)的,如果不了解?ThreadLocal,請(qǐng)自行查閱;

spring security 權(quán)限校驗(yàn)流程:

1. 第一次請(qǐng)求http://localhost:8088/persons方法時(shí),UsernamePasswordAuthenticationFilter? 不會(huì)攔截,因?yàn)閁sernamePasswordAuthenticationFilter? 只會(huì)攔截/login 且為POST,? 但是會(huì)被AnonymousAuthenticationFilter攔截,主要做的就是SecurityContextHolder.getContext().setAuthentication(AnonymousAuthenticationToken),具體請(qǐng)看源碼;然后會(huì)進(jìn)入到FilterSecurityInterceptor過(guò)濾器;FilterSecurityInterceptor 過(guò)濾器才是真正控制訪(fǎng)問(wèn)權(quán)限的Filter;

2. super.beforeInvocation(fi) 主要邏輯:

1)Authentication authenticated =this.authenticateIfRequired();?? 獲取token,從SecurityContextHolder.getContext()? 獲得

2)this.accessDecisionManager.decide(authenticated, object,attributes); ******這個(gè)才是重中之重*****作用就是判斷是否有訪(fǎng)問(wèn)權(quán)限;

?3. this.accessDecisionManager.decide(authenticated, object,attributes);會(huì)拋出AccessDeniedException |AuthenticationException異常,并被ExceptionTranslationFilter攔截,

如果為AccessDeniedException ,跳轉(zhuǎn)到未授權(quán)頁(yè)面

如果為AuthenticationException,跳轉(zhuǎn)登錄頁(yè)面

4. 由于未登錄跳轉(zhuǎn)到登錄頁(yè)

5. 填寫(xiě)用戶(hù)名和密碼再次請(qǐng)求,會(huì)走上面的認(rèn)證流程;? 認(rèn)證流程走完,最終還是會(huì)走到FilterSecurityInterceptor? 攔截器;然后還是會(huì)從? 2) 流程開(kāi)始走,不同的是這回已經(jīng)登錄,所以Authentication authenticated =this.authenticateIfRequired();獲取到的是包含用戶(hù)數(shù)據(jù),以及權(quán)限的信息;然后還是會(huì)走this.accessDecisionManager.decide(authenticated, object,attributes); 不拋出異常則到 第6步驟, 否則還是會(huì)從3 步驟開(kāi)始

?6. 訪(fǎng)問(wèn)到/persons 接口,進(jìn)入到Controller 中;

以上流程圖源自:

http://www.spring4all.com/article/439

http://www.spring4all.com/article/458

關(guān)鍵的類(lèi)和接口介紹:

AbstractAuthenticationProcessingFilter 類(lèi):在不同maven包下的展現(xiàn)形式:

spring-boot-starter-security包下:

spring-boot-starter-security

spring-security-oauth2包下:

spring-security-oauth2

可以看出多了一個(gè)OAuth2ClientAuthenticationProcessingFilter和ClientCredentialsTokenEndpointFilter;

當(dāng)使用Oauth2認(rèn)證時(shí),主要走的兩個(gè)Filter;

AuthenticationManager 接口:認(rèn)證時(shí)主要是PrividerManager 實(shí)現(xiàn)類(lèi)去做認(rèn)證;

PrividerManager 實(shí)現(xiàn)類(lèi)中主要的方法和屬性介紹:

認(rèn)證器集合:providers

authenticate 方法:

1. 遍歷認(rèn)證器.

2.判斷認(rèn)證器是否支持token的認(rèn)證

3.如果支持,進(jìn)行具體的認(rèn)證邏輯

AuthenticationProvider 接口:

AbstractUserDetailsAuthenticationProvider 抽象類(lèi):

authenticate 方法:

子類(lèi)實(shí)現(xiàn)retrieveUser 方法,通過(guò)不同的方式獲取UserDetails;

DaoAuthenticationProvider 實(shí)現(xiàn)類(lèi)(去實(shí)現(xiàn)retrieveUser ):

retrieveUser方法:

DaoAuthenticationProvider? 方法

通過(guò)UserDetailsService 對(duì)象獲取UserDetails對(duì)象;

UserDetailsService? 屬性:

DaoAuthenticationProvider? 屬性

UserDetailsService 接口:

spring-boot-starter-security包下:

spring-boot-starter-security

spring-security-oauth2包下:

spring-security-oauth2

可以看出在spring-security-oauth2包下多一個(gè)ClientDetailsUserDetailsService類(lèi),這個(gè)也就是spring security實(shí)現(xiàn)Oauth2的主要認(rèn)證類(lèi);

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容