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
相关产品推荐
相关产品推荐

