Spring Boot3 Webflux响应式应用集成内部认证栈的预认证实现咨询
Spring Boot 3 响应式Web应用接入内部预认证栈实现方案
在响应式WebFlux体系中,Spring Security不再依赖Servlet Filter链,而是基于SecurityWebFilterChain和响应式组件实现认证逻辑。替代MVC中AbstractPreAuthenticatedProcessingFilter的核心思路是:自定义凭证提取转换器、响应式认证管理器,并整合到安全配置中。
核心实现步骤
1. 实现ServerAuthenticationConverter:提取请求中的认证凭证
这个组件负责从ServerHttpRequest中提取内部认证所需的凭证(比如请求头、Cookie中的令牌),对应原AbstractPreAuthenticatedProcessingFilter里的凭证提取逻辑。
import org.springframework.security.core.Authentication; import org.springframework.security.web.server.authentication.ServerAuthenticationConverter; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken; public class InternalAuthConverter implements ServerAuthenticationConverter { // 根据内部认证栈约定,指定凭证所在的请求头 private static final String INTERNAL_TOKEN_HEADER = "X-Internal-Auth-Token"; @Override public Mono<Authentication> convert(ServerWebExchange exchange) { // 从请求头提取凭证,转换为预认证Token return Mono.justOrEmpty(exchange.getRequest().getHeaders().getFirst(INTERNAL_TOKEN_HEADER)) .map(token -> new PreAuthenticatedAuthenticationToken(token, null)); } }
2. 实现ReactiveAuthenticationManager:对接内部认证栈验证凭证
这个组件负责调用内部认证栈验证凭证合法性,并返回已认证的Authentication对象,对应原Filter中的认证逻辑。
import org.springframework.security.authentication.ReactiveAuthenticationManager; import org.springframework.security.core.Authentication; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken; import reactor.core.publisher.Mono; import org.springframework.security.authentication.BadCredentialsException; // 假设InternalAuthService是你内部认证栈的服务类,需自行注入 public class InternalAuthManager implements ReactiveAuthenticationManager { private final InternalAuthService internalAuthService; public InternalAuthManager(InternalAuthService internalAuthService) { this.internalAuthService = internalAuthService; } @Override public Mono<Authentication> authenticate(Authentication authentication) { String token = authentication.getPrincipal().toString(); // 调用内部认证栈验证令牌,获取用户权限信息 return internalAuthService.validateTokenAndGetUserInfo(token) .map(userInfo -> { // 构建已认证的UserDetails和Authentication对象 UserDetails userDetails = User.withUsername(userInfo.getUserId()) .password("") // 预认证场景无需密码 .authorities(userInfo.getRoles().toArray(new String[0])) .build(); return new PreAuthenticatedAuthenticationToken(userDetails, token, userDetails.getAuthorities()); }) // 验证失败时抛出认证异常 .onErrorResume(e -> Mono.error(new BadCredentialsException("Invalid internal auth token"))); } }
3. 配置SecurityWebFilterChain:整合组件到安全链
将上面两个自定义组件整合到Spring Security的响应式安全配置中,替换或添加到认证流程里。
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity; import org.springframework.security.config.web.server.ServerHttpSecurity; import org.springframework.security.web.server.SecurityWebFilterChain; import org.springframework.security.web.server.authentication.AuthenticationWebFilter; import org.springframework.http.HttpStatus; @Configuration @EnableWebFluxSecurity public class ReactiveSecurityConfig { @Bean public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http, ReactiveAuthenticationManager internalAuthManager) { // 创建自定义认证过滤器,绑定转换器和管理器 AuthenticationWebFilter authFilter = new AuthenticationWebFilter(internalAuthManager); authFilter.setServerAuthenticationConverter(new InternalAuthConverter()); return http .csrf(ServerHttpSecurity.CsrfSpec::disable) // 根据业务需求决定是否关闭CSRF .authorizeExchange(exchanges -> exchanges .anyExchange().authenticated()) // 所有请求需认证 // 将自定义过滤器添加到认证链的对应位置 .addFilterAt(authFilter, ServerHttpSecurity.AuthorizeExchangeSpec.AUTHENTICATION_FILTER) // 可选:配置认证失败的响应逻辑 .exceptionHandling(exceptions -> exceptions .authenticationEntryPoint((exchange, ex) -> { exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED); return exchange.getResponse().setComplete(); })) .build(); } @Bean public ReactiveAuthenticationManager internalAuthManager(InternalAuthService internalAuthService) { return new InternalAuthManager(internalAuthService); } }
补充说明
PreAuthenticatedAuthenticationToken是Spring Security提供的预认证专用Token,适用于凭证已被外部/内部系统预先验证的场景。- 如果需要从Cookie、请求参数等其他位置提取凭证,只需修改
InternalAuthConverter的convert方法逻辑即可。 - 若需自定义SecurityContext的存储(比如存入分布式缓存),可以实现
ServerSecurityContextRepository并在配置中通过http.securityContextRepository(customRepo)指定。
内容的提问来源于stack exchange,提问作者Marc
相关产品推荐
相关产品推荐

