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

Spring Security 6自定义过滤器致所有请求403问题咨询

问题解决方案

1. 配置SecurityContextHolder全局存储策略

默认SecurityContextHolder使用MODE_THREADLOCAL存储上下文,线程切换(如Spring Observability观测逻辑)时会导致上下文丢失。需设置为可继承的线程本地存储,确保认证信息在跨线程场景下不丢失:

@PostConstruct
public void initSecurityContextStrategy() {
    SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL);
}

将这段代码添加到配置类或自定义过滤器类中,保证应用启动时生效。

2. 禁用Spring Security默认匿名认证过滤器

Spring Security会自动注入AnonymousAuthenticationFilter,可能覆盖自定义过滤器设置的认证信息,导致授权时识别为匿名。需在SecurityFilterChain中显式禁用:
修改securityFilterChain配置:

@Bean
@Order(0)
public SecurityFilterChain securityFilterChain(
      HttpSecurity http,
      @Qualifier(OpaqueTokenAuthorizationFilter.OPAQUE_TOKEN_AUTHORIZATION_FILTER)
          OncePerRequestFilter authorizationFilter
  ) throws Exception {
    http
            .authorizeHttpRequests(auth -> auth.anyRequest().authenticated())
            .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
            .addFilterBefore(authorizationFilter, UsernamePasswordAuthenticationFilter.class)
            // 禁用默认匿名认证过滤器
            .anonymous(AbstractHttpConfigurer::disable);
    return http.build();
}

3. 确认过滤器执行优先级

虽然自定义过滤器已标注@Order(Ordered.HIGHEST_PRECEDENCE),但仍需确保它通过addFilterBefore添加后,确实在所有Spring Security认证/授权过滤器之前执行。可通过打印过滤器链顺序验证,或直接使用addFilterAt固定其在UsernamePasswordAuthenticationFilter之前的执行位置。

问题本质

该问题核心是SecurityContext在线程传递中丢失,或被默认匿名过滤器覆盖。ObservationDecisionManager执行授权决策时,线程上下文已无自定义设置的认证信息,因此判定为匿名认证。调整存储策略+禁用默认匿名过滤器即可解决。


内容的提问来源于stack exchange,提问作者Alisher

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 01:30:21