Appearance
Spring Security 源码级原理解析
入口不是 HttpSecurity
运行时入口是 Servlet Filter,不是配置类。真正处理请求的是 FilterChainProxy。
java
SecurityContext context = SecurityContextHolder.getContext();
Authentication authentication = context.getAuthentication();DelegatingFilterProxy -> FilterChainProxy
Servlet 容器注册的是 DelegatingFilterProxy,它只负责从 Spring 容器拿到名为 springSecurityFilterChain 的 Bean 并调用。
源码层面要点:
- 容器只认标准
Filter - Spring Security 借代理桥接到 IoC 容器
- 真正的安全逻辑全部挂在
FilterChainProxy
FilterChainProxy 做的事情
FilterChainProxy 会维护多条 SecurityFilterChain。
一次请求进来后:
- 用
RequestMatcher找第一条匹配链。 - 拿到该链上的过滤器集合。
- 依次执行过滤器。
这也是 Spring Security 6 推荐多条 SecurityFilterChain Bean 的原因,匹配与执行天然分离。
SecurityContextHolder
默认策略是 MODE_THREADLOCAL。认证成功后的 Authentication 会被放进当前线程的 SecurityContext。
java
Authentication result = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(username, password));
SecurityContextHolder.getContext().setAuthentication(result);运行时含义:
- 控制器里直接注入
Authentication,本质上就是从上下文取值。 - 同一线程中的后续授权逻辑共享这份身份信息。
- 线程池复用时必须清理上下文。
ProviderManager
AuthenticationManager 默认实现通常是 ProviderManager。它像责任链:
- 逐个问
AuthenticationProvider是否supports - 找到支持者后执行
authenticate - 成功返回完整的认证对象
java
@Bean
AuthenticationManager authenticationManager(AuthenticationConfiguration configuration) throws Exception {
return configuration.getAuthenticationManager();
}DaoAuthenticationProvider
这是用户名密码场景的核心 Provider:
- 调用
UserDetailsService.loadUserByUsername - 取回
UserDetails - 用
PasswordEncoder校验密码 - 组装已认证
Authentication
java
@Service
class CustomUserDetailsService implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) {
return User.withUsername(username)
.password("{noop}123456")
.authorities("ROLE_USER")
.build();
}
}授权入口
Spring Security 6 的请求授权核心落在 AuthorizationFilter 和 AuthorizationManager。
java
http.authorizeHttpRequests(auth -> auth
.requestMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated());机制上不是简单字符串判断,而是:
- 读取当前
Authentication - 结合当前请求对象
- 交给
AuthorizationManager计算结果
一条请求的内部状态变化
text
未认证请求
-> 过滤器读取凭证
-> AuthenticationManager 认证
-> SecurityContextHolder 写入身份
-> AuthorizationFilter 鉴权
-> Controller
-> 清理上下文