On this page
21. WebClient
Note
以下文档供在 Reactive 环境中使用。对于 Servlet 环境,请参考Servlet 的 WebClient环境。
Spring Framework 内置了对设置 Bearer 令牌的支持。
webClient.get()
.headers(h -> h.setBearerAuth(token))
...
Spring Security 在此支持的基础上提供了其他好处:
Spring Security 将自动刷新过期的令牌(如果存在刷新令牌)
如果请求访问令牌但不存在,则 Spring Security 将自动请求访问令牌。
对于 authorization_code,这涉及执行重定向,然后重播原始请求
- 对于 client_credentials,只需请求并保存令牌
支持透明包含当前 OAuth 令牌或明确选择应使用的令牌的功能。
21.1 WebClient OAuth2 设置
第一步是确保正确设置WebClient。在完全反应的环境中设置WebClient的示例如下:
@Bean
WebClient webClient(ReactiveClientRegistrationRepository clientRegistrations,
ServerOAuth2AuthorizedClientRepository authorizedClients) {
ServerOAuth2AuthorizedClientExchangeFilterFunction oauth =
new ServerOAuth2AuthorizedClientExchangeFilterFunction(clientRegistrations, authorizedClients);
// (optional) explicitly opt into using the oauth2Login to provide an access token implicitly
// oauth.setDefaultOAuth2AuthorizedClient(true);
// (optional) set a default ClientRegistration.registrationId
// oauth.setDefaultClientRegistrationId("client-registration-id");
return WebClient.builder()
.filter(oauth)
.build();
}
21.2 隐式 OAuth2AuthorizedClient
如果我们将defaultOAuth2AuthorizedClient设置为有效的ClientRegistration id 的truein our setup and the user authenticated with oauth2Login (i.e. OIDC), then the current authentication is used to automatically provide the access token. Alternatively, if we set defaultClientRegistrationId,则该注册将用于提供访问令牌。这很方便,但是在并非所有端点都应获取访问令牌的环境中,这样做很危险(您可能为端点提供了错误的访问令牌)。
Mono<String> body = this.webClient
.get()
.uri(this.uri)
.retrieve()
.bodyToMono(String.class);
21.3 显式 OAuth2AuthorizedClient
OAuth2AuthorizedClient可以通过在请求属性上设置来明确提供。在下面的示例中,我们使用 Spring WebFlux 或 Spring MVC 参数解析器支持来解析OAuth2AuthorizedClient。但是,OAuth2AuthorizedClient的解析方式无关紧要。
@GetMapping("/explicit")
Mono<String> explicit(@RegisteredOAuth2AuthorizedClient("client-id") OAuth2AuthorizedClient authorizedClient) {
return this.webClient
.get()
.uri(this.uri)
.attributes(oauth2AuthorizedClient(authorizedClient))
.retrieve()
.bodyToMono(String.class);
}
21.4 clientRegistrationId
或者,可以在请求属性上指定clientRegistrationId,而WebClient将尝试查找OAuth2AuthorizedClient。如果找不到,将自动获取一个。
Mono<String> body = this.webClient
.get()
.uri(this.uri)
.attributes(clientRegistrationId("client-id"))
.retrieve()
.bodyToMono(String.class);