Springboot(十)springsecurity認證流程源碼分析

用戶認證流程

這裏我們簡單從springsecurity源碼中分析用戶認證流程

當用戶發送登入請求首先會進入UsernamePasswordAuthenticationFilter並調用
attemptAuthentication()方法獲取用戶名密碼
在這裏插入圖片描述
從源碼我們可以看到獲取的用戶參數信息放在了UsernamePasswordAuthenticationToken對象中,
在UsernamePasswordAuthenticationToken構造方法中,調用了父類的構造器並傳入一個null,爲什麼是null呢?因爲剛開始並沒有認證,因此用戶沒有任何權限,並且設置沒有認證的信息(setAuthenticated(false))
在這裏插入圖片描述
UsernamePasswordAuthenticationToken構建完成後繼續執行
this.getAuthenticationManager().authenticate(authRequest)

實際就是執行AuthenticationManager接口中的方法authenticate方法

AuthenticationManager接口實現類很多,這裏會使用ProviderManager
在這裏插入圖片描述
ProvideManager負責管理AuthenticationProvider,我們可以看到圖中有很多的providers,可以有SocialAuthenticationProvider(第三方接入的時候專用,比如qq登錄,微信登錄等),AbstractUserDetailsAuthenticationProvider(我們配置的時候用到的)等等。其實真正執行的只有一個provider,那麼究竟會選擇哪一個provider,我們看到有一個supports方法。也就是根據上一步中的authentication的類型來做判斷。
在這裏插入圖片描述
如果支持則會進入AuthenticationProvider接口的抽象實現類AbstractUserDetailsAuthenticationProvider中調用 authenticate(Authentication authentication)方法對用戶的身份進入校驗。進入抽象類AbstractUserDetailsAuthenticationProvider的內部的authenticate方法之後,先會判斷user是否爲空,這個user是UserDetail的對象,如果爲空,表示還沒有認證,就需要調用retrieveUser方法去獲取用戶的信息,這個方法是抽象類AbstractUserDetailsAuthenticationProvider的擴展類DaoAuthenticationProvider的一個方法

在這裏插入圖片描述
在該擴展類的retrieveUser方法中調用UserDetailsService這個接口的實現類的loadUserByUsername方法去獲取用戶信息。在這裏插入圖片描述
而這裏我自己編寫了實現類MyUserDetail類,在這個實現類中,我們可以編寫自己的邏輯,從數據庫中獲取用戶密碼等權限信息返回

在這裏插入圖片描述
在這裏插入圖片描述
在獲取到用戶信息後 繼續回到AbstractUserDetailsAuthenticationProvider類中調用createSuccessAuthentication(principalToReturn, authentication, user)方法

在這裏插入圖片描述

在該方法中會調用三個參數的UsernamePasswordAuthenticationToken構造器,不同於前面調用兩個參數的,因爲這裏已經驗證了用戶的信息和權限,因此不再是給父類構造器中傳null值了,而是用戶的權限集合,並且設置認證通過(setAuthenticated(true))

protected Authentication createSuccessAuthentication(Object principal, Authentication authentication, UserDetails user) {
        UsernamePasswordAuthenticationToken result = new UsernamePasswordAuthenticationToken(principal, authentication.getCredentials(), 
        this.authoritiesMapper.mapAuthorities(user.getAuthorities()));
        result.setDetails(authentication.getDetails());
        return result;
    }

在這裏插入圖片描述
用戶的所有權限
在UsernamePasswordAuthenticationToken的父類中,它會檢查用的權限,如果有一個爲null,表示權限沒有相應的權限,拋出異常
在這裏插入圖片描述

然後在createSuccessAuthentication方法返回後回到ProvioderManager的authenticate方法中返回result,最後回到UsernamePasswordAuthenticationFilter的剛開始進入的attemptAuthentication方法中返回

通過上面的源碼我們已經深入源碼瞭解到用戶的具體認證流程。這裏簡單總結一下,首先當用戶發送請求的時候,會進入到UsernamePasswordAuthenticationFilter中得到一個UsernamePasswordAuthenticationToken,它其實相當於一個令牌,不過還沒有經過認證,然後調用AuthenticationManager的實現類ProviderManager中判斷登錄方式是否支持,如果支持,則會調用AuthenticationProvider接口的抽象實現類AbstractUserDetailsAuthenticationProvider中調用它的擴展類DaoAuthenticationProvider中獲取我們自己實現的MyUserDetails類獲取用戶密碼進行用戶身份驗證,然後返回該對象,設置UsernamePasswordAuthenticationToken這個令牌認證通過,用戶身份校驗成功

參考

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章