目录
一、核心角色对应(责任链模式)
二、核心架构:双层责任链设计
1. 外层:FilterChainProxy(全局过滤器入口)
2. 内层:SecurityFilterChain(具体过滤器链)
三、核心流程(以表单登录为例)
关键特点:
四、代码示例:自定义过滤器链
步骤 1:自定义认证过滤器(具体处理者)
步骤 2:配置过滤器链(责任链管理器)
步骤 3:核心业务(Controller,责任链终点)
五、核心过滤器(内置具体处理者)
六、责任链的核心实现(源码简化)
1. FilterChainProxy(外层管理器)
2. 关键逻辑:
七、Spring Security 责任链的核心特点
1. 高度可定制
2. 中断性与容错性
3. 解耦性
八、典型应用场景
九、与 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 认证、自定义授权)的核心前提。