Spring Security 的安全功能通过一系列过滤器(Filter)组成的链式结构实现,每个过滤器负责处理特定的安全任务。这些过滤器按特定顺序执行,形成过滤器链(Security Filter Chain)。以下是其核心过滤器及工作原理的详细解析:
一、默认过滤器链(按执行顺序)
过滤器名称(类名) | 作用 |
---|---|
1. SecurityContextPersistenceFilter | 从 Session 加载或创建 SecurityContext (存储认证信息)。 |
2. HeaderWriterFilter | 写入安全相关的 HTTP 头(如 X-Content-Type-Options 、X-Frame-Options )。 |
3. CsrfFilter | 检查 CSRF Token(防止跨站请求伪造)。默认保护非 GET 、HEAD 、TRACE 、OPTIONS 请求。 |
4. LogoutFilter | 处理注销请求(默认路径 /logout ),清除安全上下文和 Session。 |
5. UsernamePasswordAuthenticationFilter | 处理表单登录(默认路径 /login ),提取用户名密码并认证。 |
6. DefaultLoginPageGeneratingFilter | 生成默认登录页(当未配置自定义登录页时生效)。 |
7. DefaultLogoutPageGeneratingFilter | 生成默认注销页。 |
8. BasicAuthenticationFilter | 处理 HTTP Basic 认证(Authorization: Basic <token> )。 |
9. RequestCacheAwareFilter | 缓存请求,用于登录成功后恢复原始请求(如访问 /admin 被拦截后跳转登录页)。 |
10. SecurityContextHolderAwareRequestFilter | 包装请求对象(HttpServletRequest ),提供安全相关方法(如 isUserInRole )。 |
11. AnonymousAuthenticationFilter | 为未认证用户分配匿名身份(默认角色 ROLE_ANONYMOUS )。 |
12. SessionManagementFilter | 管理会话(如并发控制、会话固定攻击防护)。 |
13. ExceptionTranslationFilter | 处理认证/授权异常,触发 AuthenticationEntryPoint (如跳转登录页)或返回 403。 |
14. FilterSecurityInterceptor | 最终授权决策,调用 AccessDecisionManager 验证用户是否有权访问资源。 |
二、过滤器链工作原理
1. 责任链模式(Chain of Responsibility)
• 执行顺序:请求按过滤器链的顺序依次通过每个过滤器,每个过滤器可选择处理请求或传递给下一个过滤器。
• 终止条件:当某个过滤器处理完请求并直接返回响应时,后续过滤器不再执行。
2. 核心流程
HTTP 请求 → 过滤器1 → 过滤器2 → ... → 过滤器N → 访问资源
↓ ↓ ↓
处理逻辑 处理逻辑 处理逻辑
• 认证流程:
• UsernamePasswordAuthenticationFilter
提取凭证并认证 → 存储 Authentication
到 SecurityContextHolder
。
• 授权流程:
• FilterSecurityInterceptor
最终验证权限 → 若未授权则抛出 AccessDeniedException
。
• 异常处理:
• ExceptionTranslationFilter
捕获异常 → 触发登录页跳转或返回 403。
3. 关键交互示例
用户访问受保护资源(如 `/admin`):
1. SecurityContextPersistenceFilter 加载 SecurityContext(若已登录则存在 Authentication)。
2. AnonymousAuthenticationFilter 为未认证用户赋予匿名身份。
3. FilterSecurityInterceptor 检查权限 → 发现未认证 → 抛出 AccessDeniedException。
4. ExceptionTranslationFilter 捕获异常 → 调用 AuthenticationEntryPoint 跳转登录页。
5. 用户提交登录表单 → UsernamePasswordAuthenticationFilter 认证成功 → 更新 SecurityContext。
6. 用户再次访问 `/admin` → FilterSecurityInterceptor 验证权限 → 允许访问。
三、如何查看和配置过滤器链
1. 查看默认过滤器链
在日志中设置 DEBUG
级别:
logging.level.org.springframework.security.web.FilterChainProxy=DEBUG
启动应用后,日志会输出默认过滤器链顺序:
Security filter chain: [
WebAsyncManagerIntegrationFilter
SecurityContextPersistenceFilter
HeaderWriterFilter
CsrfFilter
LogoutFilter
...
]
2. 自定义过滤器链
通过 HttpSecurity
配置添加、移除或调整过滤器:
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
// 禁用默认表单登录过滤器
.formLogin(AbstractHttpConfigurer::disable)
// 添加自定义过滤器(如 JWT 过滤器)
.addFilterBefore(jwtAuthFilter(), UsernamePasswordAuthenticationFilter.class)
// 配置权限规则
.authorizeHttpRequests(auth -> auth
.requestMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().permitAll()
);
return http.build();
}
四、常见过滤器的扩展场景
1. 添加自定义过滤器
public class CustomAuthFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) {
// 自定义认证逻辑(如验证请求头中的 Token)
chain.doFilter(request, response);
}
}
// 注册到过滤器链
http.addFilterBefore(new CustomAuthFilter(), BasicAuthenticationFilter.class);
2. 禁用默认过滤器
http.csrf(csrf -> csrf.disable()); // 禁用 CSRF 防护
3. 调整过滤器顺序
// 将自定义过滤器插入到 CsrfFilter 之后
http.addFilterAfter(new CustomFilter(), CsrfFilter.class);
五、总结
Spring Security 的过滤器链通过责任链模式实现灵活的安全控制,核心特点包括:
- 模块化:每个过滤器专注单一职责(如认证、授权、CSRF 防护)。
- 可扩展:支持自定义过滤器插入任意位置。
- 顺序敏感:过滤器执行顺序影响安全行为(如
CsrfFilter
必须在认证过滤器之前执行)。
理解过滤器链的组成和执行逻辑,是调试安全问题和实现复杂安全需求的关键。