在 UsernamePasswordAuthenticationFilter 源碼分析 中,最後在類UsernamePasswordAuthenticationFilter
的驗證方法 attemptAuthentication()
會將用戶表單提交過來的用戶名和密碼封裝成對象委託類 AuthenticationManager
的驗證方法 authenticate()
進行身份驗證。
那麼本文主要對 AuthenticationManager
的驗證方法 authenticate()
驗證原理進行源碼分析。
AuthenticationManager 相關類圖
AuthenticationManager 驗證過程涉及到的類和接口較多,先用一張類圖說明各個類和接口之間的關係,如下:
-
AuthenticationManager
爲認證管理接口類,其定義了認證方法authenticate()\
p
roviderManager
爲認證管理類,實現了接口AuthenticationManager
,並在認證方法authenticate()
中將身份認證委託給具有認證資格的AuthenticationProvider
進行身份認證。-
AuthenticationProvider
是認證接口類,它定義了身份認證的方法 authenticate() AbstractUserDetailsAuthenticationProvider
是認證的抽象類,它實現了AuthenticationProvider
定義的認證方法authenticate();還定義了虛擬方法retrieveUser()用於查詢數據庫用戶信息
以及additionalAuthenticationChecks()用戶身份的認證(這兩個方法都是抽象方法)
-
DaoAuthenticationProvider
是繼承類AbstractUserDetailsAuthenticationProvider 該方法實現retrieveUser()和additionalAuthenticationChecks()兩個方法
DaoAuthenticationProvider
中還具有成員變量 userDetailsService [UserDetailsService]
用作用戶信息查詢,以及成員變量 passwordEncoder [PasswordEncoder]
用作密碼的加密及驗證。
userDetailsService
是在retrieveUser方法中調用用戶查詢數據庫用戶信息,passwordEncoder
在additionalAuthenticationChecks方法中使用,用於身份的認證
流程分析
1、認證的入口爲 AuthenticationManager
的 authenticate()
方法,鑑於 AuthenticationManager
是接口類,因此分析它的實現類 ProviderManager
,ProviderManager
的 authenticate()
方法代碼如下:
從圖中可以看出來ProviderManager 的
authenticate方法 是將認證交給AuthenticationProvider
來實現,接下來我們分析AuthenticationProvider
,由於AuthenticationProvider
是一個接口,那麼我們分析實現類AbstractUserDetailsAuthenticationProvider
2、AbstractUserDetailsAuthenticationProvider
的 authenticate ()方法
retrieveUser()方法是從數據庫加載用戶信息,這裏抽象出來這個方法,additionalAuthenticationChecks()方法密碼驗證,這裏也是抽象出來方法,兩個方法具體實現都是交給子類DaoAuthenticationProvider 來實現的,那麼我們來研究一下
3、DaoAuthenticationProvider的retrieveUser方法和additionalAuthenticationChecks方法
這裏是調用成員變量 userDetailsService
的方法 loadUserByUsername()
加載數據層中的用戶信息
調用了成員變量 passwordEncoder
的校驗方法 isPasswordValid()
對用戶密碼進行驗證