我应该如何使用 Spring WebClient 代表其他用户以非交互方式访问受 OAuth 保护的资源?



我有一个Spring(不是Boot)应用程序,它必须代表我们的用户以非交互方式(在计划任务中)访问一些第三方资源。这些资源使用 OAuth 2.0 进行授权。我们已经有一个工作流程,可以为我们提供所需的令牌,并使用Spring Social或我们自己的实现来访问资源,这两种方法都不是最佳的(Spring Social似乎没有维护,我们宁愿使用库而不是维护我们的OAuth"框架")。

我正在尝试使用 Spring Security 5.1 中的WebClient,但我不确定我是否正确使用它。

WebClient是这样创建的:

final ClientRegistration 3rdParty = 3rdParty();
final ReactiveClientRegistrationRepository clientRegistrationRepository =
new InMemoryReactiveClientRegistrationRepository(3rdParty);
final ReactiveOAuth2AuthorizedClientService authorizedClientService =
new InMemoryReactiveOAuth2AuthorizedClientService(clientRegistrationRepository);
final ServerOAuth2AuthorizedClientRepository authorizedClientRepository =
new AuthenticatedPrincipalServerOAuth2AuthorizedClientRepository(authorizedClientService);
final ServerOAuth2AuthorizedClientExchangeFilterFunction autorizedClientExchangeFilterFunction =
new ServerOAuth2AuthorizedClientExchangeFilterFunction(clientRegistrationRepository, authorizedClientRepository);
return WebClient.builder()
.filter(autorizedClientExchangeFilterFunction)
.build();

并以这种方式访问资源:

final OAuth2AuthorizedClient oAuth2AuthorizedClient = ... // (OAuth2AuthorizedClient with OAuth2AccessToken)
final Mono<SomeResource> someResourceMono = webClient().get()
.uri(3rdpartyUrl)
.attributes(ServerOAuth2AuthorizedClientExchangeFilterFunction.oauth2AuthorizedClient(oAuth2AuthorizedClient))
.retrieve()
.bodyToMono(SomeResource.class);

问题是我不明白ReactiveClientRegistrationRepositoryServerOAuth2AuthorizedClientRepository如何在这种方法中使用。如果我必须创建完全填充的OAuth2AuthorizedClient才能访问资源,为什么需要这些存储库?

我期望,我必须传递clientRegistrationId,一些"principalName",通过"principalName"实现我们的ReactiveOAuth2AuthorizedClientService加载OAuth2AuthorizedClient,并让ServerOAuth2AuthorizedClientRepository完成它的工作,但是我看到将主体传递给WebClient的唯一方法是使用需要完整OAuth2AuthorizedClientServerOAuth2AuthorizedClientExchangeFilterFunction#oauth2AuthorizedClient。我做错了哪一部分?

除了通过oauth2AuthorizedClient()提供OAuth2AuthorizedClient,您还可以通过clientRegistrationId()提供clientRegistrationId,并通过serverWebExchange()提供ServerWebExchange。后 2 个选项的组合将从ServerWebExchange解析Principal,并使用ReactiveClientRegistrationRepositoryServerOAuth2AuthorizedClientRepository来解决OAuth2AuthorizedClient。我知道您的用例有点不同,因为您在请求上下文之外运行 - 这只是仅供参考。

。问题是我不明白如何 ReactiveClientRegistrationRepository 和 ServerOAuth2AuthorizedClientRepository用于此方法

您仍然需要提供ReactiveClientRegistrationRepositoryServerOAuth2AuthorizedClientRepository,因为ServerOAuth2AuthorizedClientExchangeFilterFunction支持过期访问令牌的刷新(authorization_code客户端)和续订(client_credentials客户端)。

对于您的特定用例,请查看UnAuthenticatedServerOAuth2AuthorizedClientRepository,因为此实现支持在请求上下文(例如后台线程)之外运行的WebClient。下面是一个示例供您参考。

相关内容

最新更新