Spring Security登入驗證流程原始碼解析
一、登入認證基於過濾器鏈
Spring Security的登入驗證流程核心就是過濾器鏈。當一個請求到達時按照過濾器鏈的順序依次進行處理,通過所有過濾器鏈的驗證,就可以訪問API介面了。
SpringSecurity提供了多種登入認證的方式,由多種Filter過濾器來實現,比如:
- BasicAuthenticationFilter實現的是HttpBasic模式的登入認證
- UsernamePasswordAuthenticationFilter實現使用者名稱密碼的登入認證
- RememberMeAuthenticationFilter實現登入認證的“記住我”的功能
- SmsCodeAuthenticationFilter實現簡訊驗證碼登入認證
- SocialAuthenticationFilter實現社交媒體方式登入認證的處理
- Oauth2AuthenticationProcessingFilter和Oauth2ClientAuthenticationProcessingFilter實現Oauth2的鑑權方式
根據我們不同的需求實現及配置,不同的Filter會被載入到應用中。
二、結合原始碼講解登入驗證流程
我們就以使用者名稱、密碼登入方式為例講解一下Spring Security的登入認證流程。
2.1 UsernamePasswordAuthenticationFilter
該過濾器封裝使用者基本資訊(使用者名稱、密碼),定義登入表單資料接收相關的資訊。如:
- 預設的表單使用者名稱密碼input框name是username、password
- 預設的處理登入請求路徑是/login、使用POST方法
2.2 AbstractAuthenticationProcessingFilter的doFilter方法的驗證過程
UsernamePasswordAuthenticationFilter繼承自抽象類AbstractAuthenticationProcessingFilter,該抽象類定義了驗證成功與驗證失敗的處理方法。
2.3 驗證成功之後的Handler和驗證失敗之後的handler
也就是說當我們需要自定義驗證成功或失敗的處理方法時,要去實現AuthenticationSuccessHandler或AuthenticationfailureHandler介面
三、登入驗證內部細節
3.1多種認證方式的管理 ProviderManager
ProviderManager用繼承於AuthenticationManager是登入驗證的核心類。ProviderManager保管了多個AuthenticationProvider,用於不同型別的登入驗證。比如:
- RememberMeAuthenticationProvider定義了“記住我”功能的登入驗證邏輯
- DaoAuthenticationProvider載入資料庫使用者資訊,進行使用者密碼的登入驗證
public class ProviderManager implements AuthenticationManager, MessageSourceAware, InitializingBean {
……
private List<AuthenticationProvider> providers;
……
下文是ProviderManager的核心原始碼,遍歷不同登入驗證的AuthenticationProvider,只有當這種方式被支援的時候,才執行具體的登入驗證邏輯。
3.2 登入認證介面 AuthenticationProvider
public interface AuthenticationProvider {
Authentication authenticate(Authentication var1) throws AuthenticationException;
boolean supports(Class<?> var1);
}
AuthenticationProvider的實現類定義了具體的登入驗證邏輯
3.3 資料庫載入使用者資訊 DaoAuthenticationProvider
public class DaoAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {
從資料庫獲取使用者資訊原始碼
所以當我們需要載入使用者資訊進行登入驗證的時候,我們需要實現UserDetailsService
介面,重寫loadUserByUsername
方法,引數是使用者輸入的使用者名稱。返回值是UserDetails
。
期待您的關注
- 博主最近新寫了一本書:《手摸手教您學習SpringBoot系列-16章97節》
- 本文轉載註明出處(必須帶連線,不能只轉文字):字母哥部落格。