Spring Boot 2.7.7中如何忽略匿名请求的Authorization头?
当前配置中,虽然通过RequestHeaderRequestMatcher允许了带abcd:myabcdValue头的请求匿名访问,但OAuth2资源服务器的过滤器会优先处理Authorization头,尝试解析JWT token,一旦token无效就直接触发认证失败,不会进入后续的授权逻辑判断。以下是两种可行的解决方法:
方案1:拆分过滤器链,跳过指定请求的OAuth2校验
通过securityMatcher划分请求范围,让带指定头的请求不经过OAuth2过滤器,直接放行:
public SecurityFilterChain resourceServerSecurityFilterChain(HttpSecurity http) throws Exception { // 定义不需要OAuth2校验的请求匹配器 RequestMatcher skipOAuthMatcher = new RequestHeaderRequestMatcher("abcd", "myabcdValue"); // 定义需要OAuth2校验的请求匹配器:排除上述请求 RequestMatcher oauthMatcher = new NegatedRequestMatcher(skipOAuthMatcher); http .csrf().disable() // 处理无需OAuth2校验的请求,直接全部放行 .securityMatcher(skipOAuthMatcher) .authorizeRequests(auth -> auth.anyRequest().permitAll()) .and() // 处理需要OAuth2校验的请求,应用原有配置 .securityMatcher(oauthMatcher) .authorizeRequests(auth -> auth .antMatchers("/").permitAll() .antMatchers("/csrf").permitAll() .antMatchers("/api/**").permitAll() .antMatchers("/swagger-ui/**", "/swagger-resources/**", "/webjars/**", "/v2/api-docs", "/v3/api-docs").permitAll() .requestMatchers(EndpointRequest.to("info", "health")).permitAll() .anyRequest().authenticated() ) .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .oauth2ResourceServer(oauth -> oauth .accessDeniedHandler(exceptionHandler) .authenticationEntryPoint(exceptionHandler) .jwt(jwt -> jwt .decoder(jwtDecoder) .jwtAuthenticationConverter(new JwtRolesConverter()) ) ); return http.build(); }
方案2:自定义JWT认证转换器,动态跳过校验
在JWT认证转换逻辑中判断请求头,当检测到abcd:myabcdValue时,直接返回匿名认证对象,跳过token校验:
首先实现自定义转换器:
public class SkipJwtForHeaderConverter implements JwtAuthenticationConverter { private final JwtAuthenticationConverter delegate = new JwtRolesConverter(); private final RequestHeaderRequestMatcher matcher = new RequestHeaderRequestMatcher("abcd", "myabcdValue"); @Override public Authentication convert(Jwt jwt) { HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); if (matcher.matches(request)) { // 返回匿名认证,跳过token校验 return new AnonymousAuthenticationToken("anonymous", "anonymous", Collections.emptyList()); } // 其他请求走正常JWT转换逻辑 return delegate.convert(jwt); } }
然后替换配置中的转换器:
.oauth2ResourceServer(oauth -> oauth .accessDeniedHandler(exceptionHandler) .authenticationEntryPoint(exceptionHandler) .jwt(jwt -> jwt .decoder(jwtDecoder) .jwtAuthenticationConverter(new SkipJwtForHeaderConverter()) ) )
注:该方案需确保Spring MVC环境下RequestContextHolder能正常获取当前请求,默认环境均支持。
内容的提问来源于stack exchange,提问作者Patan
相关产品推荐
相关产品推荐

