Spring Security自定义过滤器未触发:为何请求未被过滤?
以下是针对你的问题的具体排查方向和修复方案:
1. 过滤器实例管理问题
你的AuthorizationFilter标注了@Component,同时在SpringConfig中通过@Resource注入,这种方式可能导致实例重复或上下文不一致。建议改为在配置类中直接创建过滤器Bean,确保它被Spring Security上下文正确管理:
修改SpringConfig,移除@Resource注入,添加过滤器Bean定义:
@Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) public class SpringConfig { @Bean public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception { return authenticationConfiguration.getAuthenticationManager(); } // 直接创建AuthorizationFilter Bean @Bean public AuthorizationFilter authorizationFilter(ExternalAuthenticationService externalAuthenticationService) { return new AuthorizationFilter(externalAuthenticationService); } @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { // ... 原有配置代码 ... http.addFilterBefore(authorizationFilter(), UsernamePasswordAuthenticationFilter.class); return http.build(); } }
同时移除AuthorizationFilter类上的@Component注解,避免Spring自动扫描生成多余实例。
2. 过滤器链顺序错误
在Spring Security中,过滤器的执行顺序直接影响功能生效。你当前在authorizeRequests()之后添加过滤器,可能导致权限校验在认证之前执行。调整顺序,将过滤器添加逻辑放在权限配置之前:
@Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { // 启用CORS、禁用CSRF http = http.cors().and().csrf().disable(); // 无状态会话管理 http = http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and(); // 异常处理配置 http = http.exceptionHandling() .authenticationEntryPoint((request, response, ex) -> { response.sendError(HttpServletResponse.SC_UNAUTHORIZED, ex.getMessage()); }).and(); // 先添加JWT过滤器 http.addFilterBefore(authorizationFilter(), UsernamePasswordAuthenticationFilter.class); // 再配置权限规则 http.authorizeRequests() .anyRequest().authenticated(); return http.build(); }
3. 放行OPTIONS预检请求
REST API的CORS预检请求(OPTIONS方法)通常不会携带Authorization头,若未显式放行,会在权限校验阶段被拦截,无法到达你的过滤器。添加OPTIONS请求的放行规则:
http.authorizeRequests() .antMatchers(HttpMethod.OPTIONS, "/**").permitAll() // 放行所有OPTIONS请求 .anyRequest().authenticated();
4. 强制所有请求经过过滤器
OncePerRequestFilter默认会跳过转发(FORWARD)或包含(INCLUDE)类型的请求,若你的请求属于这类,过滤器不会执行。重写shouldNotFilter方法,强制所有请求进入过滤逻辑:
public class AuthorizationFilter extends OncePerRequestFilter { // ... 原有代码 ... @Override protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException { // 返回false表示不跳过任何请求 return false; } }
5. 开启详细调试日志
开启Spring Security的DEBUG级别日志,能直观看到过滤器链的执行顺序和每个过滤器的调用情况:
在application.properties中添加:
logging.level.org.springframework.security=DEBUG
日志中会输出类似SecurityFilterChain executing Filters的内容,你可以检查自己的AuthorizationFilter是否在链中,以及执行顺序是否正确。
内容的提问来源于stack exchange,提问作者Tobia

