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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 18:37:45