This is now resolved. Demo usage can be found in oauth2webclient and oauth2webclient-webflux samples. A quick tour of the support:
WebClient has built in support for easily adding a Bearer token. For example:
webClient.get()
.headers(h -> h.setBearerAuth(token))
...
Spring Security provides first class support for OAuth2. A few advantages of using this support are:
The first step is ensuring to setup the WebClient correctly.
For a Servlet environment this looks like:
@Bean
WebClient webClient(ClientRegistrationRepository clientRegistrationRepository, OAuth2AuthorizedClientRepository authorizedClientRepository) {
ServletOAuth2AuthorizedClientExchangeFilterFunction oauth2 = new ServletOAuth2AuthorizedClientExchangeFilterFunction(clientRegistrationRepository, authorizedClientRepository);
// (optional) explicitly opt into using the oauth2Login to provide an access token implicitly
oauth2.setDefaultOAuth2AuthorizedClient(true);
return WebClient.builder()
.apply(oauth2.oauth2Configuration())
.build();
}
For other (i.e. WebFlux) environments it looks like:
@Bean
WebClient webClient(ReactiveClientRegistrationRepository clientRegistrationRepository,
ServerOAuth2AuthorizedClientRepository authorizedClientRepository) {
ServerOAuth2AuthorizedClientExchangeFilterFunction oauth =
new ServerOAuth2AuthorizedClientExchangeFilterFunction(clientRegistrationRepository, authorizedClientRepository);
// (optional) explicitly opt into using the oauth2Login to provide an access token implicitly
oauth.setDefaultOAuth2AuthorizedClient(true);
return WebClient.builder()
.filter(oauth)
.build();
}
If we set defaultOAuth2AuthorizedClient to true in our setup and the user authenticated with oauth2Login (i.e. OIDC), then the current authentication is used to automatically provide the access token. This is convenient, but in environments where not all endpoints should get the access token, it is dangerous (you might provide the wrong access token to an endpoint).
Mono<String> body = this.webClient
.get()
.uri(this.uri)
.retrieve()
.bodyToMono(String.class);
You can also explicitly provide an OAuth2AuthorizedClient by setting it on the requests attributes. In the example below we resolve the OAuth2AuthorizedClient using Spring WebFlux or Spring MVC argument resolver support. However, the user can choose to resolve the OAuth2AuthorizedClient however they wish.
@GetMapping("/explicit")
Mono<String> explicit(@RegisteredOAuth2AuthorizedClient("client-id") OAuth2AuthorizedClient authorizedClient) {
return this.webClient
.get()
.uri(this.uri)
.attributes(oauth2AuthorizedClient(authorizedClient))
.retrieve()
.bodyToMono(String.class);
}
````
## clientRegistrationId
Alternatively, it is possible to specify the `clientRegistrationId` on the request attributes and the `WebClient` will attempt to lookup the `OAuth2AuthorizedClient`. If it is not found, one will automatically be acquired.
```java
Mono<String> body = this.webClient
.get()
.uri(this.uri)
.attributes(clientRegistrationId("client-id"))
.retrieve()
.bodyToMono(String.class);
We should add OAuth + WebClient support. The support for using WebClient in a Servlet environment and WebFlux must be separate because:
This is going to be broken up into multiple issues:
Here is some context :
Spring Security OAuth 2 had support for OAuth2RestTemplate that allowed clients to contact a Resource server by providing a ResourceDetail containing OAuth2 info.
Using WebClient requires the client to handle the token retrieval. Would be nice if that feature from OAuth2RestTemplate could be ported to Spring Security 5.
@rwinch @jgrandja
I have an important request regarding that OAuth 2 support. Could it be packaged as a separate lib without the server related stuff? The main reason is that our SCS client using boot picks up Oauth2 dependencies transitively. This results in boot auto-configuring OAuth2 endpoints because the current jar has boot client and server classes altogether.
The client and server(s) will be in separate modules. The client module is in spring-security-oauth2-client and when we start the Resource Server work in Jan it will be in a separate module, for example, spring-security-oauth2-resource-server. Authorization server will also going into a separate module.
Awesome !
This is now resolved in master
Does this support authorization grant type of password?
Looking in oauth2-core/src/main/java/org/springframework/security/oauth2/core/AuthorizationGrantType.java it doesn't seem to, but I might be looking in the wrong place!
@idc101 Thanks for the feedback.
You are correct. We do not yet support password grant types. Please log an issue for support if you would like to see it
Most helpful comment
Here is some context :
Spring Security OAuth 2 had support for
OAuth2RestTemplatethat allowed clients to contact a Resource server by providing aResourceDetailcontaining OAuth2 info.Using WebClient requires the client to handle the token retrieval. Would be nice if that feature from
OAuth2RestTemplatecould be ported to Spring Security 5.