目录
[1. 外层:FilterChainProxy(全局过滤器入口)](#1. 外层:FilterChainProxy(全局过滤器入口))
[2. 内层:SecurityFilterChain(具体过滤器链)](#2. 内层:SecurityFilterChain(具体过滤器链))
[步骤 1:自定义认证过滤器(具体处理者)](#步骤 1:自定义认证过滤器(具体处理者))
[步骤 2:配置过滤器链(责任链管理器)](#步骤 2:配置过滤器链(责任链管理器))
[步骤 3:核心业务(Controller,责任链终点)](#步骤 3:核心业务(Controller,责任链终点))
[1. FilterChainProxy(外层管理器)](#1. FilterChainProxy(外层管理器))
[2. 关键逻辑:](#2. 关键逻辑:)
[七、Spring Security 责任链的核心特点](#七、Spring Security 责任链的核心特点)
[1. 高度可定制](#1. 高度可定制)
[2. 中断性与容错性](#2. 中断性与容错性)
[3. 解耦性](#3. 解耦性)
[九、与 Spring MVC 拦截器链的区别](#九、与 Spring MVC 拦截器链的区别)
Spring Security 的核心架构完全基于责任链模式 设计,其核心载体是 过滤器链(SecurityFilterChain) ------ 将认证、授权、防护等安全逻辑拆分为独立的过滤器(Filter),请求沿过滤器链按序执行,每个过滤器负责单一安全职责,最终实现完整的安全校验流程。
核心目标:将复杂的安全逻辑解耦为可插拔的过滤器组件,支持灵活扩展和定制(如新增验证码校验、JWT 认证、接口限流等)。
一、核心角色对应(责任链模式)
| 责任链模式角色 | Spring Security 对应实现 | 核心职责 |
|---|---|---|
| 抽象处理者(Handler) | javax.servlet.Filter(Servlet 过滤器)/ OncePerRequestFilter |
定义过滤器核心方法 doFilter(),约定请求处理规则(Spring Security 过滤器多继承 OncePerRequestFilter 保证单次请求仅执行一次) |
| 具体处理者 | 内置过滤器(如 UsernamePasswordAuthenticationFilter、JwtAuthenticationFilter)/ 自定义过滤器 |
实现特定安全逻辑(认证、授权、CSRF 防护等),通过 chain.doFilter() 传递请求 |
| 责任链管理器 | FilterChainProxy + SecurityFilterChain |
FilterChainProxy 是顶级入口,匹配请求对应的 SecurityFilterChain,触发过滤器链执行 |
| 请求对象 | HttpServletRequest/HttpServletResponse |
被过滤器链处理的核心对象 |
| 最终处理者 | 目标资源(Controller / 静态资源) | 过滤器链执行完成后,请求传递到核心业务逻辑 |
二、核心架构:双层责任链设计
Spring Security 的责任链分为两层,保证 "多规则适配 + 顺序执行":
1. 外层:FilterChainProxy(全局过滤器入口)
FilterChainProxy 是 Spring Security 注册到 Servlet 容器的唯一过滤器(通过 DelegatingFilterProxy 适配),其核心作用是:
- 根据请求路径匹配对应的
SecurityFilterChain(支持多套过滤器链,如/api/**一套、/admin/**另一套); - 触发匹配到的
SecurityFilterChain执行。
2. 内层:SecurityFilterChain(具体过滤器链)
每个 SecurityFilterChain 包含一组有序的过滤器(List<Filter>),是真正执行安全逻辑的责任链,例如:
plaintext
UsernamePasswordAuthenticationFilter(表单登录认证)→
BasicAuthenticationFilter(Basic 认证)→
JwtAuthenticationFilter(JWT 认证)→
FilterSecurityInterceptor(授权校验)→
ExceptionTranslationFilter(异常处理)
三、核心流程(以表单登录为例)
plaintext
客户端请求 →
Tomcat → DelegatingFilterProxy → FilterChainProxy →
匹配 SecurityFilterChain → 执行过滤器链:
1. CsrfFilter(CSRF 防护)→
2. UsernamePasswordAuthenticationFilter(表单登录认证)→
3. BasicAuthenticationFilter(Basic 认证,跳过)→
4. FilterSecurityInterceptor(授权校验)→
5. ExceptionTranslationFilter(异常处理,无异常则跳过)→
传递到 DispatcherServlet → Controller(核心业务)
关键特点:
- 顺序性:过滤器按固定顺序执行(可通过配置调整),例如 "认证过滤器必须在授权过滤器前执行";
- 中断性 :过滤器可中断链(如认证失败直接返回 401,不调用
chain.doFilter()); - 匹配性 :不同请求路径可匹配不同过滤器链(如
/login走表单登录链,/api走 JWT 认证链)。
四、代码示例:自定义过滤器链
步骤 1:自定义认证过滤器(具体处理者)
实现 JWT 认证过滤器,作为责任链的具体处理者:
java
运行
@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {
@Autowired
private JwtTokenProvider jwtTokenProvider;
@Autowired
private AuthenticationManager authenticationManager;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
// 1. 提取 Token
String token = request.getHeader("Authorization");
if (token == null || !token.startsWith("Bearer ")) {
filterChain.doFilter(request, response); // 无 Token,传递给下一个过滤器
return;
}
token = token.substring(7);
// 2. 校验 Token
try {
String username = jwtTokenProvider.extractUsername(token);
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
// 3. 认证通过,存入 SecurityContext
Authentication authentication = jwtTokenProvider.getAuthentication(token);
SecurityContextHolder.getContext().setAuthentication(authentication);
System.out.println("JwtAuthenticationFilter:JWT 认证通过,用户:" + username);
}
} catch (Exception e) {
// 认证失败,中断链(返回 401)
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.getWriter().write("JWT 认证失败:" + e.getMessage());
return;
}
// 4. 传递给下一个过滤器
filterChain.doFilter(request, response);
}
}
步骤 2:配置过滤器链(责任链管理器)
通过 SecurityFilterChain 构建自定义责任链,指定过滤器顺序:
java
运行
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Autowired
private JwtAuthenticationFilter jwtAuthenticationFilter;
@Autowired
private CustomAccessDeniedHandler accessDeniedHandler; // 自定义授权失败处理器
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
// 关闭默认的 CSRF(测试环境,生产需开启)
.csrf(csrf -> csrf.disable())
// 配置请求授权规则
.authorizeHttpRequests(auth -> auth
.requestMatchers("/login").permitAll() // 登录接口放行
.requestMatchers("/api/admin/**").hasRole("ADMIN") // 管理员接口需 ADMIN 角色
.anyRequest().authenticated() // 其他请求需认证
)
// 异常处理
.exceptionHandling(ex -> ex
.accessDeniedHandler(accessDeniedHandler) // 授权失败处理
.authenticationEntryPoint((request, response, authException) -> {
// 认证失败处理
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.getWriter().write("请先认证");
})
)
// 添加自定义过滤器:插入到 UsernamePasswordAuthenticationFilter 之后
.addFilterAfter(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
return http.build();
}
// 认证管理器(用于处理用户认证)
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
return config.getAuthenticationManager();
}
// 密码编码器
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
步骤 3:核心业务(Controller,责任链终点)
java
运行
@RestController
@RequestMapping("/api")
public class UserController {
@GetMapping("/user")
public String getUser() {
return "普通用户接口";
}
@GetMapping("/admin/user")
public String getAdminUser() {
return "管理员接口";
}
}
五、核心过滤器(内置具体处理者)
Spring Security 内置了数十个过滤器,覆盖所有核心安全场景,以下是最常用的:
| 过滤器 | 核心职责 | 执行顺序(关键) |
|---|---|---|
CsrfFilter |
CSRF 防护,验证 CSRF Token | 靠前(先防护后认证) |
UsernamePasswordAuthenticationFilter |
表单登录认证,处理 /login 请求的用户名密码 |
认证类过滤器核心 |
BasicAuthenticationFilter |
Basic 认证,解析请求头中的 Authorization: Basic xxx |
表单认证之后 |
JwtAuthenticationFilter |
JWT 认证(需自定义 / 引入 spring-security-oauth2) | 可插入到认证过滤器链 |
FilterSecurityInterceptor |
授权校验,匹配 @PreAuthorize/ 角色 / 权限规则 |
认证之后(最后一个核心过滤器) |
ExceptionTranslationFilter |
捕获安全异常(如 AuthenticationException/AccessDeniedException),转换为 HTTP 响应 |
授权过滤器之前 |
LogoutFilter |
处理登出请求,清理 SecurityContext |
认证过滤器之前 |
六、责任链的核心实现(源码简化)
1. FilterChainProxy(外层管理器)
java
运行
public class FilterChainProxy extends GenericFilterBean {
private List<SecurityFilterChain> filterChains;
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
// 1. 匹配当前请求对应的 SecurityFilterChain
SecurityFilterChain filterChain = getMatchingFilterChain(req, res);
if (filterChain == null) {
chain.doFilter(req, res); // 无匹配链,直接传递
return;
}
// 2. 执行匹配到的过滤器链
VirtualFilterChain virtualFilterChain = new VirtualFilterChain(chain, filterChain.getFilters());
virtualFilterChain.doFilter(req, res);
}
// 内部类:封装具体过滤器链的执行
private static class VirtualFilterChain implements FilterChain {
private final FilterChain originalChain;
private final List<Filter> filters;
private int currentPosition = 0;
public VirtualFilterChain(FilterChain originalChain, List<Filter> filters) {
this.originalChain = originalChain;
this.filters = filters;
}
@Override
public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
if (currentPosition == filters.size()) {
// 所有过滤器执行完成,传递到原始链(DispatcherServlet)
originalChain.doFilter(request, response);
return;
}
// 按顺序执行下一个过滤器
currentPosition++;
Filter nextFilter = filters.get(currentPosition - 1);
nextFilter.doFilter(request, response, this);
}
}
}
2. 关键逻辑:
VirtualFilterChain是责任链的核心执行器,通过currentPosition记录当前执行的过滤器索引;- 每个过滤器执行完后调用
virtualFilterChain.doFilter(),实现请求的 "链式传递"; - 所有过滤器执行完成后,才会调用
originalChain.doFilter()传递到 DispatcherServlet。
七、Spring Security 责任链的核心特点
1. 高度可定制
- 顺序调整 :通过
addFilterBefore()/addFilterAfter()/addFilterAt()调整过滤器顺序(如将 JWT 过滤器插入到表单认证过滤器之后); - 链的拆分 :多套
SecurityFilterChain适配不同路径的安全规则(如前台 / 后台不同认证方式); - 过滤器扩展 :自定义过滤器只需继承
OncePerRequestFilter,注册到链中即可,无需修改原有逻辑。
2. 中断性与容错性
- 中断链 :过滤器可通过 "不调用
chain.doFilter()" 中断请求(如认证失败直接返回 401); - 异常处理 :
ExceptionTranslationFilter捕获链中异常,保证单一异常出口,避免链中断导致的资源泄漏。
3. 解耦性
- 每个过滤器仅关注单一职责(如认证、授权、CSRF),符合 "单一职责原则";
- 核心业务(Controller)无需耦合安全逻辑,通过过滤器链透明增强。
八、典型应用场景
- 多认证方式:同时支持表单登录、JWT 认证、OAuth2 认证(不同过滤器处理);
- 精细化授权 :基于角色(
hasRole)、权限(hasPermission)、IP 白名单的授权校验; - 安全防护:CSRF 防护、XSS 过滤、接口限流(自定义过滤器实现);
- 异常统一处理:认证 / 授权失败返回标准化 JSON 响应;
- 第三方集成:集成 CAS、LDAP 等认证体系(新增对应过滤器)。
九、与 Spring MVC 拦截器链的区别
| 维度 | Spring Security 过滤器链 | Spring MVC HandlerInterceptor 链 |
|---|---|---|
| 核心目的 | 安全逻辑(认证、授权、防护) | 通用请求增强(日志、参数处理) |
| 执行时机 | DispatcherServlet 之前(Servlet 容器层) | DispatcherServlet 内部 |
| 扩展能力 | 可拦截所有 Web 请求(包括静态资源) | 仅拦截 Controller 请求 |
| 依赖 | 原生 Servlet Filter,无 Spring 依赖 | 依赖 Spring 上下文,可注入 Bean |
| 中断方式 | 不调用 chain.doFilter() |
preHandle 返回 false |
总结
Spring Security 是责任链模式在 "安全领域" 的极致落地:
- 核心载体 :
FilterChainProxy+SecurityFilterChain构成双层责任链,实现 "多规则匹配 + 顺序执行"; - 核心逻辑 :每个过滤器是独立的安全处理单元,通过
chain.doFilter()传递请求,支持中断和扩展; - 核心价值:将复杂的安全逻辑解耦为可插拔的过滤器,适配不同场景的安全需求(如单体应用、微服务、前后端分离);
- 扩展关键 :自定义过滤器只需继承
OncePerRequestFilter,通过addFilterBefore/After插入到责任链中,无需修改框架源码。
掌握这一机制,是定制 Spring Security 安全规则(如 JWT 认证、自定义授权)的核心前提。