You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Security自定义过滤器未触发:为何请求未被过滤?

自定义AuthorizationFilter未被调用的排查与修复

以下是针对你的问题的具体排查方向和修复方案:

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 17:40:17