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

Spring Boot 3.x中如何配置放行无需JWT的URL路径

Spring Boot 3.0.6中permitAll路径返回401的解决方法

问题场景

在Spring Boot 3.0.6中使用如下Security配置:

@Configuration
@EnableWebSecurity
@Slf4j
public class SecurityConfig {

  private final JwtIssuerAuthenticationManagerResolver authenticationManagerResolver;
  private final OpaAuthorizationManager opaAuthorizationManager;

  @Autowired
  public SecurityConfig(@Value("${com.example.security.oauth2.resourceserver.jwt.issuer}") String[] issuer,
                        OpaAuthorizationManager opaAuthorizationManager) {
    this.authenticationManagerResolver = new JwtIssuerAuthenticationManagerResolver(issuer);
    this.opaAuthorizationManager = opaAuthorizationManager;
  }

  @Bean
  public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
        .authorizeHttpRequests((requests) -> requests
            .requestMatchers(new AntPathRequestMatcher("/health")).permitAll()
            .requestMatchers(new AntPathRequestMatcher("/openapi/openapi.yml")).permitAll()
            .anyRequest().access(this.opaAuthorizationManager))
        .oauth2ResourceServer(oauth2 -> oauth2.authenticationManagerResolver(authenticationManagerResolver));
    return http.build();
  }
}

受限路径运行正常,但配置了permitAll()的/health和/openapi/openapi.yml路径却返回HTTP 401状态码。调试发现DefaultBearerTokenResolver抛出OAuth2AuthenticationException,触发未授权的/error路径渲染,最终返回401,自定义AuthorizationManager未被调用(符合预期)。需要让这些放行路径无需JWT和授权即可访问。

解决方案

方案一:拆分安全规则,让放行路径跳过OAuth2资源服务器过滤器

Spring Security的OAuth2资源服务器过滤器会在授权校验前执行,即便路径配置了permitAll,若请求携带无效Bearer Token仍会被拦截。可通过securityMatcher拆分配置,为不同路径组应用不同规则:

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    // 放行路径:不启用OAuth2资源服务器规则,直接允许访问
    http.securityMatcher(new AntPathRequestMatcher("/health"), new AntPathRequestMatcher("/openapi/openapi.yml"))
        .authorizeHttpRequests(auth -> auth.anyRequest().permitAll())
        .csrf(csrf -> csrf.disable());

    // 受限路径:启用OAuth2资源服务器和自定义授权规则
    http.securityMatcher(new AntPathRequestMatcher("/**"))
        .authorizeHttpRequests(auth -> auth.anyRequest().access(this.opaAuthorizationManager))
        .oauth2ResourceServer(oauth2 -> oauth2.authenticationManagerResolver(authenticationManagerResolver));

    return http.build();
}

方案二:自定义BearerTokenResolver,禁止无效Token抛出异常

修改DefaultBearerTokenResolver的配置,让其在Token无效或不存在时返回null而非抛出异常,这样授权校验阶段会直接放行permitAll路径:

首先定义自定义的BearerTokenResolver:

@Bean
public BearerTokenResolver bearerTokenResolver() {
    DefaultBearerTokenResolver resolver = new DefaultBearerTokenResolver();
    // 关闭无效Token时抛出异常的行为
    resolver.setThrowExceptionOnInvalidToken(false);
    return resolver;
}

然后在Security配置中使用该解析器:

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
        .authorizeHttpRequests((requests) -> requests
            .requestMatchers(new AntPathRequestMatcher("/health")).permitAll()
            .requestMatchers(new AntPathRequestMatcher("/openapi/openapi.yml")).permitAll()
            .anyRequest().access(this.opaAuthorizationManager))
        .oauth2ResourceServer(oauth2 -> oauth2
            .authenticationManagerResolver(authenticationManagerResolver)
            .bearerTokenResolver(bearerTokenResolver()) // 使用自定义解析器
        );
    return http.build();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 21:25:29