以下是 Spring Boot 3.x 下 Spring Security 的執行流程、核心類和原理詳解,結合用戶描述的關鍵點展開說明,并以表格總結:
1. Spring Security 核心原理
Spring Security 通過 Filter 鏈 實現安全控制,其核心流程如下:
- 啟動階段:
- 引入
spring-boot-starter-security
后,Spring Boot 自動配置SecurityAutoConfiguration
。 - 通過
@EnableWebSecurity
注解觸發安全框架的初始化,創建SecurityFilterChain
Bean(名稱為springSecurityFilterChain
)。
- 引入
- Filter 注冊:
DelegatingFilterProxy
攔截所有請求,從 Spring 容器中獲取springSecurityFilterChain
(類型FilterChainProxy
)。FilterChainProxy
管理多個Filter
對象(如UsernamePasswordAuthenticationFilter
、CsrfFilter
等),按順序執行攔截邏輯。
- 請求處理:
- 每個請求經過
FilterChainProxy
的doFilter()
方法,依次調用攔截器鏈中的 Filter,完成認證、授權、CSRF 防護等功能。
- 每個請求經過
2. 關鍵類與流程詳解
(1) Spring Security 啟動流程
-
依賴引入:
<!-- Maven 依賴 --> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId> </dependency>
- 引入后,Spring Boot 自動啟用
SecurityAutoConfiguration
。
- 引入后,Spring Boot 自動啟用
-
Bean 創建:
@EnableWebSecurity
注解觸發WebSecurityConfiguration
,創建SecurityFilterChain
Bean(名稱springSecurityFilterChain
)。SecurityFilterChain
實際類型為FilterChainProxy
,包含多個Filter
對象。
-
自動配置日志:
Using generated security password: <random-generated-password>
- 默認啟用安全配置時,Spring Boot 會生成隨機密碼(可通過
management.security.enabled=false
禁用)。
- 默認啟用安全配置時,Spring Boot 會生成隨機密碼(可通過
(2) 核心類與協作關系
類名 | 作用 | 關鍵方法/屬性 |
---|---|---|
FilterChainProxy | 核心過濾器鏈,管理所有安全 Filter 的執行順序。 | getFilters() :獲取 Filter 列表 |
DelegatingFilterProxy | Servlet 容器的適配器,將請求委托給 Spring 容器中的 FilterChainProxy 。 | initFilterBean() :初始化并獲取 Bean |
SecurityFilterChain | 安全過濾器鏈的抽象接口,由 FilterChainProxy 實現。 | getFilters() :定義 Filter 順序 |
WebSecurityConfigurerAdapter | 過時配置類(Spring Boot 2.x),現改用 SecurityFilterChain Bean。 | 已棄用,需改用 @Bean SecurityFilterChain |
UsernamePasswordAuthenticationFilter | 處理表單登錄認證的 Filter。 | attemptAuthentication() :驗證用戶憑證 |
CsrfFilter | 處理 CSRF 令牌生成與驗證。 | getToken() :獲取 CSRF Token |
(3) FilterChainProxy 的執行流程
- 初始化:
- 通過
DelegatingFilterProxy
從 Spring 容器獲取springSecurityFilterChain
Bean。
- 通過
- 請求攔截:
- 每個請求到達
DelegatingFilterProxy
后,調用FilterChainProxy
的doFilter()
方法。 FilterChainProxy
遍歷filters
列表,按順序執行每個 Filter 的doFilter()
。
- 每個請求到達
- Filter 順序:
- 默認順序由
SecurityFilterChain
定義(如:ChannelProcessingFilter
→WebAsyncManagerIntegrationFilter
→ …)。 - 可通過
SecurityFilterChain
自定義 Filter 順序。
- 默認順序由
(4) 配置注解對比
注解 | 適用場景 | 功能 |
---|---|---|
@EnableWebSecurity | Web 應用 | 啟用安全配置,創建 SecurityFilterChain ,集成 Web 特性(如表單登錄)。 |
@EnableGlobalAuthentication | 非 Web 應用(如消息服務) | 僅啟用認證功能,不包含 Web 相關 Filter(如 CSRF、表單登錄)。 |
@EnableMethodSecurity | 方法級安全控制 | 啟用 @PreAuthorize 、@PostFilter 等注解。 |
3. 自定義 Filter 的實現
(1) 創建自定義 Filter
@Component
public class CustomFilter implements Filter {@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {// 自定義邏輯(如 Token 解析)chain.doFilter(request, response);}
}
(2) 注冊到 FilterChainProxy
@Configuration
public class SecurityConfig {@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.addFilterBefore(new CustomFilter(), UsernamePasswordAuthenticationFilter.class);return http.build();}
}
4. Spring Boot 3.x 特殊說明
- 自動配置變化:
- Spring Boot 3.x 中
WebSecurityConfigurerAdapter
已棄用,需通過@Bean SecurityFilterChain
直接配置。
- Spring Boot 3.x 中
- 日志控制:
- 隨機密碼日志可通過
logging.level.org.springframework.security=ERROR
禁用。
- 隨機密碼日志可通過
5. 總結表格
模塊/組件 | 作用 | 關鍵類/注解 |
---|---|---|
啟動與配置 | 初始化安全框架,創建 Filter 鏈 | @EnableWebSecurity 、SecurityAutoConfiguration 、SecurityFilterChain |
Servlet 適配 | 將 Servlet 請求委托給 Spring 容器中的 Filter 鏈 | DelegatingFilterProxy |
Filter 鏈管理 | 管理 Filter 順序和執行邏輯 | FilterChainProxy 、SecurityFilterChain |
認證與授權 | 用戶身份驗證、權限控制 | UsernamePasswordAuthenticationFilter 、RoleVoter 、AccessDecisionManager |
擴展與自定義 | 注冊自定義 Filter 或修改安全策略 | addFilterBefore() 、addFilterAfter() 、@Bean SecurityFilterChain |
6. 執行流程圖(文字描述)
- 請求到達 Web 容器 → DelegatingFilterProxy → 獲取 springSecurityFilterChain → FilterChainProxy → 遍歷并執行所有 Filter → 最終響應。
- 每個 Filter(如
CsrfFilter
、SecurityContextPersistenceFilter
)按順序執行。
- 每個 Filter(如
通過以上流程和組件的協作,Spring Security 實現了從請求攔截到權限控制的完整安全機制。在 Spring Boot 3.x 中,需特別注意配置方式的更新(如棄用 WebSecurityConfigurerAdapter
),以確保與新版本兼容。