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 在这里提供了一个良好的开端来选择和配置正确的。
我在 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 在这里提供了一个良好的开端来选择和配置正确的。