Remove redundant docs for Reactive OAuth2 Client

Issue gh-10373
This commit is contained in:
Joe Grandja 2021-10-28 09:17:13 -04:00
parent ce09f3eff4
commit b77cb8d0cb
3 changed files with 0 additions and 240 deletions

View File

@ -96,7 +96,6 @@
*** xref:reactive/oauth2/login.adoc[OAuth2 Log In]
*** xref:reactive/oauth2/oauth2-client.adoc[OAuth2 Client]
*** xref:reactive/oauth2/resource-server.adoc[OAuth2 Resource Server]
*** xref:reactive/registered-oauth2-authorized-client.adoc[@RegisteredOAuth2AuthorizedClient]
** xref:reactive/exploits/index.adoc[Protection Against Exploits]
*** xref:reactive/exploits/csrf.adoc[CSRF]
*** xref:reactive/exploits/headers.adoc[Headers]
@ -104,6 +103,5 @@
** Integrations
*** xref:reactive/integrations/cors.adoc[CORS]
*** xref:reactive/integrations/rsocket.adoc[RSocket]
*** xref:reactive/integrations/webclient.adoc[WebClient]
** xref:reactive/test.adoc[Testing]
** xref:reactive/configuration/webflux.adoc[WebFlux Security]

View File

@ -1,175 +0,0 @@
= WebClient
[NOTE]
====
The following documentation is for use within Reactive environments.
For Servlet environments, refer to xref:servlet/oauth2/oauth2-client.adoc#oauth2Client-webclient-servlet[ WebClient for Servlet] environments.
====
Spring Framework has built in support for setting a Bearer token.
====
.Java
[source,java,role="primary"]
----
webClient.get()
.headers(h -> h.setBearerAuth(token))
...
----
.Kotlin
[source,kotlin,role="secondary"]
----
webClient.get()
.headers { it.setBearerAuth(token) }
...
----
====
Spring Security builds on this support to provide additional benefits:
* Spring Security will automatically refresh expired tokens (if a refresh token is present)
* If an access token is requested and not present, Spring Security will automatically request the access token.
** For authorization_code this involves performing the redirect and then replaying the original request
** For client_credentials the token is simply requested and saved
* Support for the ability to transparently include the current OAuth token or explicitly select which token should be used.
[[webclient-setup]]
== WebClient OAuth2 Setup
The first step is ensuring to setup the `WebClient` correctly.
An example of setting up `WebClient` in a fully reactive environment can be found below:
====
.Java
[source,java,role="primary"]
----
@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();
}
----
.Kotlin
[source,kotlin,role="secondary"]
----
@Bean
fun webClient(clientRegistrations: ReactiveClientRegistrationRepository,
authorizedClients: ServerOAuth2AuthorizedClientRepository): WebClient {
val oauth = 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()
}
----
====
[[webclient-implicit]]
== Implicit OAuth2AuthorizedClient
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.
Alternatively, if we set `defaultClientRegistrationId` to a valid `ClientRegistration` id, that registration is used to 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).
====
.Java
[source,java,role="primary"]
----
Mono<String> body = this.webClient
.get()
.uri(this.uri)
.retrieve()
.bodyToMono(String.class);
----
.Kotlin
[source,kotlin,role="secondary"]
----
val body: Mono<String> = webClient
.get()
.uri(this.uri)
.retrieve()
.bodyToMono()
----
====
[[webclient-explicit]]
== Explicit OAuth2AuthorizedClient
The `OAuth2AuthorizedClient` can be explicitly provided 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, it does not matter how the `OAuth2AuthorizedClient` is resolved.
====
.Java
[source,java,role="primary"]
----
@GetMapping("/explicit")
Mono<String> explicit(@RegisteredOAuth2AuthorizedClient("client-id") OAuth2AuthorizedClient authorizedClient) {
return this.webClient
.get()
.uri(this.uri)
.attributes(oauth2AuthorizedClient(authorizedClient))
.retrieve()
.bodyToMono(String.class);
}
----
.Kotlin
[source,kotlin,role="secondary"]
----
@GetMapping("/explicit")
fun explicit(@RegisteredOAuth2AuthorizedClient("client-id") authorizedClient: OAuth2AuthorizedClient?): Mono<String> {
return this.webClient
.get()
.uri(uri)
.attributes(oauth2AuthorizedClient(authorizedClient))
.retrieve()
.bodyToMono()
}
----
====
[[webclient-clientregistrationid]]
== 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
[source,java,role="primary"]
----
Mono<String> body = this.webClient
.get()
.uri(this.uri)
.attributes(clientRegistrationId("client-id"))
.retrieve()
.bodyToMono(String.class);
----
.Kotlin
[source,kotlin,role="secondary"]
----
val body: Mono<String> = this.webClient
.get()
.uri(uri)
.attributes(clientRegistrationId("client-id"))
.retrieve()
.bodyToMono()
----
====

View File

@ -1,63 +0,0 @@
[[webflux-roac]]
= @RegisteredOAuth2AuthorizedClient
Spring Security allows resolving an access token using `@RegisteredOAuth2AuthorizedClient`.
[NOTE]
====
A working example can be found in {gh-samples-url}/reactive/webflux/java/oauth2/webclient[*OAuth 2.0 WebClient WebFlux sample*].
====
After configuring Spring Security for xref:reactive/oauth2/login.adoc#webflux-oauth2-login[OAuth2 Login] or as an xref:reactive/oauth2/oauth2-client.adoc#webflux-oauth2-client[OAuth2 Client], an `OAuth2AuthorizedClient` can be resolved using the following:
====
.Java
[source,java,role="primary"]
----
@GetMapping("/explicit")
Mono<String> explicit(@RegisteredOAuth2AuthorizedClient("client-id") OAuth2AuthorizedClient authorizedClient) {
// ...
}
----
.Kotlin
[source,kotlin,role="secondary"]
----
@GetMapping("/explicit")
fun explicit(@RegisteredOAuth2AuthorizedClient("client-id") authorizedClient: OAuth2AuthorizedClient?): Mono<String> {
// ...
}
----
====
This integrates into Spring Security to provide the following features:
* Spring Security will automatically refresh expired tokens (if a refresh token is present)
* If an access token is requested and not present, Spring Security will automatically request the access token.
** For `authorization_code` this involves performing the redirect and then replaying the original request
** For `client_credentials` the token is simply requested and saved
If the user authenticated using `oauth2Login()`, then the `client-id` is optional.
For example, the following would work:
====
.Java
[source,java,role="primary"]
----
@GetMapping("/implicit")
Mono<String> implicit(@RegisteredOAuth2AuthorizedClient OAuth2AuthorizedClient authorizedClient) {
// ...
}
----
.Kotlin
[source,kotlin,role="secondary"]
----
@GetMapping("/implicit")
fun implicit(@RegisteredOAuth2AuthorizedClient authorizedClient: OAuth2AuthorizedClient?): Mono<String> {
// ...
}
----
====
This is convenient if the user always authenticates with OAuth2 Login and an access token from the same authorization server is needed.