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

Spring Webflux BFF架构下如何获取JWT调用资源服务?

在Spring Webflux BFF架构中实现带Token Relay的WebClient调用下游服务

针对你在BFF的/api/auth/me接口中需要调用用户服务的场景,符合Spring规范的最优方案是配置一个自动携带OAuth2 AccessToken的WebClient,利用Spring Security OAuth2提供的组件自动处理Token的获取与转发,无需手动操作会话或Token存储。

步骤1:配置支持Token Relay的WebClient Builder

创建配置类,通过OAuth2AuthorizedClientExchangeFilterFunction为WebClient添加自动携带Token的能力,该过滤器会从当前请求的认证上下文(即你的Redis会话)中获取有效的AccessToken并添加到下游请求头。

@Configuration
public class WebClientConfig {

    @Bean
    public WebClient usersServiceWebClient(ReactiveClientRegistrationRepository clientRegistrationRepository,
                                           ServerOAuth2AuthorizedClientRepository authorizedClientRepository) {
        // 创建OAuth2过滤器,用于自动注入AccessToken
        OAuth2AuthorizedClientExchangeFilterFunction oauth2Filter =
                new OAuth2AuthorizedClientExchangeFilterFunction(clientRegistrationRepository, authorizedClientRepository);
        // 指定你在配置文件中定义的Cognito客户端注册ID(需与application.yml中的client registration id一致)
        oauth2Filter.setDefaultClientRegistrationId("cognito");
        
        return WebClient.builder()
                .baseUrl("https://your-users-service-url") // 替换为用户服务的实际基础地址
                .filter(oauth2Filter)
                .build();
    }
}

步骤2:在控制器中注入并使用该WebClient

修改你的CurrentUserController,通过构造注入配置好的WebClient,调用用户服务时会自动携带AccessToken,逻辑与TokenRelay过滤器的转发行为一致。

@RestController
@RequestMapping("/api/auth")
public class CurrentUserController {

    private final WebClient usersServiceWebClient;

    // 构造注入WebClient
    public CurrentUserController(WebClient usersServiceWebClient) {
        this.usersServiceWebClient = usersServiceWebClient;
    }

    @GetMapping("/me")
    public Mono<UserResponseDTO> getCurrentUser(Authentication authentication) {
        String userId = ((DefaultOidcUser) authentication.getPrincipal()).getClaim("custom:userId");
        
        // 调用用户服务,WebClient会自动添加Authorization: Bearer <token>请求头
        return usersServiceWebClient.get()
                .uri("/api/users/{userId}", userId)
                .retrieve()
                .bodyToMono(UserResponseDTO.class);
    }
}

关键说明

  • 该方案完全基于Spring Security OAuth2的标准组件,无需手动从Redis或Cookie中提取Token:ServerOAuth2AuthorizedClientRepository会自动从会话中获取当前用户对应的OAuth2AuthorizedClient实例,其中包含有效的AccessToken。
  • 你之前尝试的WebClient未自动携带Token,是因为缺少OAuth2AuthorizedClientExchangeFilterFunction这个核心过滤器,它是实现自动Token Relay的关键。
  • 确保配置文件中已正确定义Cognito的客户端注册信息(示例配置如下):
spring:
  security:
    oauth2:
      client:
        registration:
          cognito:
            client-id: 你的Cognito客户端ID
            client-secret: 你的Cognito客户端密钥
            scope: openid, email, profile
            authorization-grant-type: authorization_code
            redirect-uri: "{baseUrl}/login/oauth2/code/cognito"
        provider:
          cognito:
            issuer-uri: https://cognito-idp.你的区域.amazonaws.com/你的用户池ID

内容的提问来源于stack exchange,提问作者Juan Aguilar Guisado

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 05:12:47