Spring Security 进阶:过滤器链与认证流程源码分析
约 994 字大约 3 分钟
布欧-Lewyon
2026-05-16
首页 › Spring Boot › 安全入门 › Spring Security 进阶
建议先阅读 Spring Security 基础掌握基本配置后,再深入了解内部架构。
Spring Security 的底层架构分三层:Servlet 容器 Filter → DelegatingFilterProxy → FilterChainProxy → SecurityFilterChain → 认证/授权 Filter 链。
架构全景
Layer 1:DelegatingFilterProxy
Spring Security 的第一个关键入口是一个 Servlet 标准的 Filter,名为 DelegatingFilterProxy。它由 AbstractSecurityWebApplicationInitializer 或 SecurityFilterAutoConfiguration 在 Spring Boot 启动时注册到内嵌容器的 Filter 链中。
// 核心逻辑(源码简化)
public class DelegatingFilterProxy extends GenericFilterBean {
private String targetBeanName = "springSecurityFilterChain";
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
// 从 ApplicationContext 中获取名为 "springSecurityFilterChain" 的 Bean
FilterChainProxy delegate = findBean(targetBeanName);
// 将控制权交给真正的安全过滤链
delegate.doFilter(request, response, chain);
}
}DelegatingFilterProxy 本身不做任何安全检查,它的作用仅仅是"桥接"——让 Servlet 容器的 Filter 链能调用到 Spring 容器中的 Bean。
Layer 2:FilterChainProxy
FilterChainProxy 是 Spring Security 的核心入口 Bean,由 @EnableWebSecurity 触发 WebSecurityConfiguration 自动配置创建。它管理一个 SecurityFilterChain 列表。
// 核心逻辑(源码简化)
public class FilterChainProxy extends GenericFilterBean {
private List<SecurityFilterChain> filterChains; // 可配置多条链
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
doFilterInternal(request, response, chain);
}
private void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) {
// 遍历所有 SecurityFilterChain,找到第一个匹配当前请求的
for (SecurityFilterChain filterChain : this.filterChains) {
if (filterChain.matches(request)) {
// 执行该链上的所有 Filter
filterChain.getFilters().forEach(filter -> filter.doFilter(request, response, chain));
return;
}
}
// 无匹配则执行默认链
chain.doFilter(request, response);
}
}SecurityFilterChain 由两部分组成:一个 RequestMatcher(决定该链匹配哪些请求)和一个 Filter 列表。通过 HttpSecurity.securityMatcher("/api/**") 可以创建专用的 Filter 链。
Layer 3:Authentication 流程
认证的核心 Filter 是 AbstractAuthenticationProcessingFilter(表单登录使用 UsernamePasswordAuthenticationFilter),其执行逻辑:
SecurityContextHolder 存储策略
SecurityContextHolder 使用三种策略控制 SecurityContext 的存储范围:
// ThreadLocal:当前线程可访问(默认)
SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_THREADLOCAL);
// InheritableThreadLocal:子线程继承父线程的 SecurityContext
// ★ 用于 @Async 异步调用场景
SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL);
// Global:所有线程共享一个 SecurityContext(极少用)
SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_GLOBAL);生产意识:Boot 4 虚拟线程默认启用时,
MODE_THREADLOCAL存在风险——虚拟线程是轻量级线程,由 JVM 调度挂载到平台线程,ThreadLocal在虚拟线程复用时可能出现上下文污染。建议通过spring.security.strategy=MODE_INHERITABLETHREADLOCAL设置,或在异步链路中使用SecurityContextHolder的DeferredSecurityContext机制传递上下文。此外,SecurityContextHolderFilter在每个请求结束后自动清除上下文,防止线程池复用导致上下文残留——这是 Spring Security 6+ 替代SecurityContextPersistenceFilter的原因之一。
小结
- 三层架构:
DelegatingFilterProxy(桥接)→FilterChainProxy(路由)→SecurityFilterChain(Filter 列表)。 - 认证流程:
AuthenticationFilter提取凭证 →ProviderManager委派AuthenticationProvider→UserDetailsService加载用户 → 密码匹配 → 写入SecurityContextHolder。 - 默认 Filter 链约 15 个 Filter,关键节点:
SecurityContextHolderFilter、ExceptionTranslationFilter、AuthorizationFilter。 SecurityContextHolder三种策略:MODE_THREADLOCAL(默认)、MODE_INHERITABLETHREADLOCAL(异步调用)、MODE_GLOBAL。- 易错:
SecurityContextHolder的MODE_THREADLOCAL在@Async/ 虚拟线程下可能失效,应使用MODE_INHERITABLETHREADLOCAL或手动传递SecurityContext。 - 思考任务:翻阅
FilterChainProxy源码,确认启动时注册的默认 Filter 列表;在@Async方法中获取SecurityContext,验证MODE_THREADLOCAL下的行为。
下一节:生产部署
