Spring 带有 WebClient 和 OAuth 客户端凭据的 MVC Servlet

Spring MVC Servlet with WebClient and OAuth Client Credentials

我在 Spring 基于 MVC servlet 的应用程序(非反应性)中使用 WebClient 来通过 HTTP 从其他微服务访问资源。 client_credentials OAuth2 流程保护的资源很少。使用 OAuth2 客户端凭据配置 RestTemplate 非常方便,但现在我无法使用 WebClient 配置相同的配置。我总是可以手动获取 Bearer 令牌,然后在 WebCLient setBearerAuth() 方法中设置它,但这需要大量的手动管道。我的问题是 - 当在 Spring MVC 应用程序中使用时,WebClient 是否支持自动客户端凭据流的 Exchange 过滤器?

更新: 我发现 ServletOAuth2AuthorizedClientExchangeFilterFunction 应该可以解决客户端凭据身份验证流程。我正在使用以下代码:

@Bean
WebClient webClient(ClientRegistrationRepository clientRegistrations, OAuth2AuthorizedClientRepository authorizedClients) {
    ServletOAuth2AuthorizedClientExchangeFilterFunction oauth2 =
            new ServletOAuth2AuthorizedClientExchangeFilterFunction(clientRegistrations, authorizedClients);
    oauth2.setDefaultClientRegistrationId("cart67");
    oauth2.setDefaultOAuth2AuthorizedClient(true);
    final WebClient webClient = WebClient.builder()
            .apply(oauth2.oauth2Configuration())
            .build();
    return webClient;
}

但现在的问题是,当从计划作业调用时,此 WebClient 无法调用远程资源服务器。我收到以下错误:

reactor.core.Exceptions$ErrorCallbackNotImplemented: 
           java.lang.IllegalArgumentException: request cannot be null
Caused by: java.lang.IllegalArgumentException: request cannot be null
at org.springframework.util.Assert.notNull(Assert.java:198)
Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:

如果我从 MVC 控制器而不是计划的作业中使用此 WebClient,则一切正常。如有任何帮助,我们将不胜感激。

这可能来自 HttpSessionOAuth2AuthorizationRequestRepository,它用于将 OAuth2AuthorizationRequest 存储在 HttpSession 中。由于您的应用程序可以很好地处理由您的控制器处理的传入 HTTP 请求,因此这是有道理的。

您可能希望以不同方式配置您的 OAuth2AuthorizedClientRepository,并且不要将信息存储在 HttpSession 中。

Spring Security documentation 在这里提供了一个良好的开端来选择和配置正确的。