當前位置:名人名言大全網 - 短信平臺 - Spring Security解析九:AuthenticationManager

Spring Security解析九:AuthenticationManager

在Spring Security中對用戶進行認證的是AuthenticationManager,其只有壹個方法,嘗試對封裝了認證信息的Authentication進行身份驗證,如果成功,則返回完全填充的Authentication(包括授予的權限)。

AuthenticationManager 只關註認證成功與否而並不關心具體的認證方式。例如我們可以通過用戶名及密碼、短信、刷臉、OAuth2協議等方式進行認證。對於這些具體認證方式是交給了AuthenticationProvider來負責。

下面展示了AuthenticationProvider的部分實現

AuthenticationManager與AuthenticationProvider 是怎麽被創建使用,以及如何自由的添加認證方式的問題,在下面的內容中將進壹步分析

前面章節分析了WebSecurityConfiguration配置類裏面相關的內容,現在回到@EnableWebSecurity 註解上,我們接著分析下@EnableGlobalAuthentication內部都做了些啥

其重點就是導入了AuthenticationConfiguration配置對象

AuthenticationConfiguration 中還導入了ObjectPostProcessorConfiguration配置,該配置比較簡單,就是實例化了壹個bean,而該Bean在前面的章節中也在不斷的用到

下面,我們深入分析下AuthenticationConfiguration配置類的實現。

先簡單的說下AuthenticationManager構建的主體過程

由上門可知,其默認使用DefaultPasswordEncoderAuthenticationManagerBuilder作為認證管理的構建器,下面分析其build()方法的執行過程。

DefaultPasswordEncoderAuthenticationManagerBuilder在執行build()方法時,其父類AbstractConfiguredSecurityBuilder的doBuild()方法被執行,前面有說過,這個方法是個模板方法,如下所示:

接著我們分析下這三個默認的GlobalAuthenticationConfigurerAdapter類型的實例中init和configure方法都做了啥

該類的目的純粹是為了添加InitializeUserDetailsManagerConfigurer配置,通過在其configure方法階段創建DaoAuthenticationProvider對象,最終被添加到ProviderManager中

Springboot的自動化配置中會默認創建InMemoryUserDetailsManager,請參考 Spring Security解析二:自動化裝配

我們也可以通過配置來指定,例如:

接著進壹步研究下DaoAuthenticationProvider都做了些啥,它是怎麽對身份進行認證的?

可見上的操作主要是從某個地方得到用戶信息,然後檢查用戶的狀態,如果檢查失敗則拋出相應的異常,否則返回成功的認證信息。

上面的retrieveUser與additionalAuthenticationChecks是需要繼續研究的地方

上面通過userDetailsService來得到用戶的信息,並通過passwordEncoder來驗證密碼是否正確,而這兩個對象是通過上面 3.2小結裏的InitializeUserDetailsManagerConfigurer中從ApplicationContext獲得。

該類的目的純粹是為了添加InitializeUserDetailsManagerConfigurer配置,通過在其configure方法階段從ApplicationContext中得到AuthenticationProvider類型的Bean,並加入到ProviderManager中

小結:

經過上來的步驟後,在DefaultPasswordEncoderAuthenticationManagerBuilder的authenticationProviders屬性中添加了壹個或多個AuthenticationProvider,接下來的工作便是執行DefaultPasswordEncoderAuthenticationManagerBuilder的performBuild()方法完成AuthenticationManager的創建工作。當然,其實該方法是在父類AuthenticationManagerBuilder中的。

返回的其實是ProviderManager,而ProviderManager可以看成是AuthenticationManager的代理對象,裏面保存了多個AuthenticationManager的實現。

Spring Security默認情況下為我們創建了壹個基於用戶名和密碼進行驗證的AuthenticationManager實例,同時收集ApplicationContext中的AuthenticationProvider類型的Bean 壹起添加到ProviderManager(AuthenticationManager的子類)中供需要的地方進行使用。