Spring Boot 3.2 Webflux如何兼容两种Bearer Token认证方式?
Spring Boot 3.2 Webflux + OAuth2 Resource Server 兼容两种Bearer Token认证方案
核心思路
通过自定义Token解析器支持两种Authorization前缀(bespoke/Bearer),再用复合认证管理器实现两种Token的验证及降级逻辑——先尝试自定义Token校验,失败后自动降级到JWT校验,全程复用Spring Security原生组件,代码简洁且符合框架设计。
步骤1:自定义BearerTokenResolver支持双前缀
扩展默认的DefaultBearerTokenResolver,新增对bespoke前缀的Token提取逻辑:
import org.springframework.security.oauth2.server.resource.web.BearerTokenResolver; import org.springframework.security.oauth2.server.resource.web.DefaultBearerTokenResolver; import org.springframework.util.StringUtils; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; public class MultiSchemeBearerTokenResolver implements BearerTokenResolver { private final DefaultBearerTokenResolver defaultResolver = new DefaultBearerTokenResolver(); @Override public Mono<String> resolve(ServerWebExchange exchange) { String authHeader = exchange.getRequest().getHeaders().getFirst("Authorization"); // 处理自定义bespoke前缀的Token if (StringUtils.hasText(authHeader) && authHeader.startsWith("bespoke ")) { return Mono.just(authHeader.substring("bespoke ".length())); } // 降级到默认的Bearer前缀处理 return defaultResolver.resolve(exchange); } }
步骤2:实现自定义Token的认证管理器
编写处理遗留bespoke Token的认证逻辑:
import org.springframework.security.authentication.ReactiveAuthenticationManager; import org.springframework.security.core.Authentication; import reactor.core.publisher.Mono; public class BespokeTokenAuthenticationManager implements ReactiveAuthenticationManager { @Override public Mono<Authentication> authenticate(Authentication authentication) { String token = (String) authentication.getPrincipal(); // 替换为实际的自定义Token校验逻辑(如调用遗留校验服务、解析用户信息) if (isValidBespokeToken(token)) { // 返回认证成功的Authentication对象,示例用UsernamePasswordAuthenticationToken return Mono.just(new org.springframework.security.authentication.UsernamePasswordAuthenticationToken( "legacy-user", null, java.util.Collections.emptyList() )); } // 校验失败,返回empty让后续认证管理器尝试 return Mono.empty(); } private boolean isValidBespokeToken(String token) { // 示例校验规则:Token以legacy-开头 return token.startsWith("legacy-"); } }
步骤3:配置复合认证管理器与Security链
组合自定义认证逻辑和JWT认证逻辑,配置到Webflux Security中:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.CompositeReactiveAuthenticationManager; import org.springframework.security.authentication.ReactiveAuthenticationManager; import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity; import org.springframework.security.config.web.server.ServerHttpSecurity; import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder; import org.springframework.security.oauth2.server.resource.authentication.JwtReactiveAuthenticationManager; import org.springframework.security.oauth2.server.resource.web.BearerTokenResolver; import org.springframework.security.web.server.SecurityWebFilterChain; @Configuration @EnableWebFluxSecurity public class SecurityConfig { private final ReactiveJwtDecoder jwtDecoder; // 注入Spring Boot自动配置的JWT解码器(需配置resourceserver.jwt相关参数) public SecurityConfig(ReactiveJwtDecoder jwtDecoder) { this.jwtDecoder = jwtDecoder; } @Bean public BearerTokenResolver multiSchemeBearerTokenResolver() { return new MultiSchemeBearerTokenResolver(); } @Bean public ReactiveAuthenticationManager compositeAuthenticationManager() { BespokeTokenAuthenticationManager bespokeManager = new BespokeTokenAuthenticationManager(); JwtReactiveAuthenticationManager jwtManager = new JwtReactiveAuthenticationManager(jwtDecoder); // 顺序决定降级逻辑:先试自定义Token,失败则用JWT return new CompositeReactiveAuthenticationManager(bespokeManager, jwtManager); } @Bean public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) throws Exception { http .authorizeExchange(exchanges -> exchanges.anyExchange().authenticated()) .oauth2ResourceServer(oauth2 -> oauth2 .bearerTokenResolver(multiSchemeBearerTokenResolver()) .authenticationManager(compositeAuthenticationManager()) ); return http.build(); } }
方案优势
- 代码简洁:仅需扩展2个类,复用Spring Security原生组件,无需复杂自定义逻辑
- 天然支持降级:
CompositeReactiveAuthenticationManager会自动依次尝试所有管理器,前一个校验失败则自动走下一个 - 适配Webflux异步模型:所有逻辑均基于Mono实现,符合非阻塞设计要求
内容的提问来源于stack exchange,提问作者DLL
相关产品推荐
相关产品推荐

