SpringBoot 整合 JWT 过滤器链顺序错误导致认证失效怎么办?

文章导读
调整 Spring Security 过滤器链注册顺序,将 JWT 认证过滤器置于用户名密码过滤器之前。适用场景为基于 Spring Security 6+ 的安全配置。风险边界是顺序错误会导致合法请求被拦截返回 401 或 403。
📋 目录
  1. 命令速用版
  2. 为什么会这样
  3. 分步处理
  4. 怎么验证是否生效
  5. 常见坑
  6. 常见问题
  7. 参考来源
A A

调整 Spring Security 过滤器链注册顺序,将 JWT 认证过滤器置于用户名密码过滤器之前。适用场景为基于 Spring Security 6+ 的安全配置。风险边界是顺序错误会导致合法请求被拦截返回 401 或 403。

先说结论:修改 SecurityFilterChain Bean 配置,显式指定 JWT 过滤器插入位置。

  • 先确认:检查 SecurityConfig 配置类中 filterChain 方法的过滤器注册代码。
  • 优先做:使用 http.addFilterBefore 方法将 JWT 过滤器添加到 UsernamePasswordAuthenticationFilter 之前。
  • 再验证:携带有效 Token 请求受保护接口,确认返回 200 而非 401。

命令速用版

此类配置问题无需 shell 命令,直接在 Java 配置类中调整代码逻辑。

@Bean
public SecurityFilterChain filterChain(HttpSecurity http, JwtAuthenticationFilter jwtAuthFilter) throws Exception {
    http.addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class)
        .authorizeHttpRequests(auth -> auth
            .requestMatchers("/api/login", "/api/register").permitAll()
            .anyRequest().authenticated()
        )
        .csrf(csrf -> csrf.disable());
    return http.build();
}

为什么会这样

Spring Security 依靠过滤器链顺序处理请求,认证必须在授权之前执行。

Spring Security 内部维护了一个 FilterChainProxy,请求到达时按顺序经过各个过滤器。如果 JWT 解析过滤器排在授权过滤器之后,请求会在未识别用户身份前就被判定为未授权,导致认证失效。官方文档明确说明了过滤器顺序对安全决策的影响。

分步处理

按顺序检查配置类、调整过滤器位置、放行特定接口。

SpringBoot 整合 JWT 过滤器链顺序错误导致认证失效怎么办?
  1. 找到项目中的 SecurityConfig 或 WebSecurityConfig 配置类。
  2. 定位定义 SecurityFilterChain 的 Bean 方法。
  3. 调用 http.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class)。
  4. 确保登录、注册等无需 Token 的接口在 authorizeHttpRequests 中配置为 permitAll。
  5. 保存代码并重启应用,确保新配置加载生效。

怎么验证是否生效

通过发送带 Token 的 HTTP 请求观察状态码和日志。

  • 使用 curl 或 Postman 请求一个需要认证的接口,Header 中携带 Authorization: Bearer <token>。
  • 检查响应状态码,正确配置应返回 200 OK,错误配置通常返回 401 Unauthorized。
  • 查看应用后台日志,确认 JWT 过滤器是否被触发且 Token 解析成功。
  • 尝试不带 Token 请求同一接口,确认是否被正确拦截返回 401。

常见坑

注意 CORS 预检请求放行和登录接口豁免配置。

  • 登录接口未放行:导致无法获取 Token,需在 authorizeHttpRequests 中 permitAll。
  • CORS 预检被拦:OPTIONS 请求可能被安全链拦截,需配置 cors 允许特定方法。
  • 过滤器顺序重复:多次添加同一过滤器可能导致逻辑执行两次或顺序混乱。
  • Token 过期处理:过滤器内需捕获 Token 过期异常并返回明确错误,避免抛出 500。

常见问题

过滤器顺序错了表现是什么?

携带有效 Token 请求受保护接口时返回 401 Unauthorized,日志显示未通过认证检查。

为什么要放在 UsernamePasswordAuthenticationFilter 之前?

该过滤器是表单登录的核心入口,放在它之前能确保自定义 JWT 逻辑优先于默认表单认证逻辑执行。

需要禁用 CSRF 吗?

JWT 通常用于无状态 API,建议禁用 CSRF 保护,避免 Cookie 相关的 CSRF 检查干扰 Token 认证。

参考来源

  • Spring Security Reference Documentation, Servlet Architecture, https://docs.spring.io/spring-security/reference/servlet/architecture.html
  • Spring Security Guide, Security Filter Chain, https://spring.io/guides/topicals/spring-security-architecture