具有自定义身份验证服务器客户端凭据的 Spring Cloud Gateway 与 WebClient 一起流动

Posted

技术标签:

【中文标题】具有自定义身份验证服务器客户端凭据的 Spring Cloud Gateway 与 WebClient 一起流动【英文标题】:Spring Cloud Gateway with Custom Auth Server client credentials flow with WebClient 【发布时间】:2021-08-20 09:00:43 【问题描述】:

我按照这个博客How can I use client_credentials to access another oauth2 resource from a resource server? 创建了一个WebClient,它将请求令牌并将其向下游转发到另一个资源服务器。这似乎工作正常,因为代码显示它正在使用 WebClient。

现在,我有一个 Spring Cloud Gateway,它想要执行此操作并请求令牌并将其转发到下游资源服务器。

我下面有如下配置。

@EnableWebFluxSecurity
public class WebClientConfig 

  @Bean
  public ReactiveOAuth2AuthorizedClientManager authorizedClientManager(
      ReactiveClientRegistrationRepository clientRegistrationRepository,
      ReactiveOAuth2AuthorizedClientService authorizedClientService) 

    ReactiveOAuth2AuthorizedClientProvider authorizedClientProvider =
        ReactiveOAuth2AuthorizedClientProviderBuilder.builder()
            .clientCredentials()
            .build();

    AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager authorizedClientManager =
        new AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager(
            clientRegistrationRepository, authorizedClientService);

    authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);

    return authorizedClientManager;
  

  @Bean
  public WebClient webClient(ReactiveOAuth2AuthorizedClientManager authorizedClientManager) 
    String registrationId = "custom";

    ServerOAuth2AuthorizedClientExchangeFilterFunction oauth = new ServerOAuth2AuthorizedClientExchangeFilterFunction(
        authorizedClientManager);

    oauth.setDefaultClientRegistrationId(registrationId);
    return WebClient.builder()
        .baseUrl("http://localhost:8888")
        .filter(oauth).build();
  

  @Bean
  public SecurityWebFilterChain configure(ServerHttpSecurity http) 
    return http
        .oauth2Client()
        .and()
        .build();
  

我的 application.yml 在下面

server:
  port: 8081
spring:
  security:
    oauth2:
      client:
        provider:
          custom:
            token-uri: http://localhost:8080/oauth/token
        registration:
          custom:
            client-id: campaign-station-client
            client-secret: password
            scope: "*"
            authorization-grant-type: client_credentials
  cloud:
    gateway:
      routes:
        - id: resource_server_id
          uri: http://localhost:8888/
          predicates:
            - Path=/resourceserver/**
          filters:
            - RewritePath=/resourceserver/(?<segment>.*), /$\segment

当我通过网关调用我的资源服务器端点时,网关不使用 WebClient 来检索访问令牌(例如 client_credentials 流)。我如何在每次调用网关时使用此 WebClient 以便将令牌下游转发到资源服务器?

【问题讨论】:

【参考方案1】:

您需要编写一个自定义过滤器,您可以从那里传递令牌。查看 TokenGatewayFilter 的代码。这会给你一个更好的主意。我也实现了。

【讨论】:

请对您的回答进行详细解释,以便下一位用户更好地理解您的回答。

以上是关于具有自定义身份验证服务器客户端凭据的 Spring Cloud Gateway 与 WebClient 一起流动的主要内容,如果未能解决你的问题,请参考以下文章

Spring OAuth2 安全 - 客户端凭据 - 自定义 AuthenticationProvider

具有 Spring Security 和 Java Config 的自定义身份验证提供程序

Spring Session + REST + 自定义身份验证过滤器(从 JSON 读取凭据而不是查询参数)

仅具有客户端凭据的 Spring 安全端点(基本)

使用 MongoDB 获取存储的用户凭据的 JAVA Spring 自定义身份验证

令牌服务器上自定义端点的 Identity Server 4 客户端凭据