@ -7,13 +7,17 @@ This section describes Spring Security's support for authorization grants.
@@ -7,13 +7,17 @@ This section describes Spring Security's support for authorization grants.
Please refer to the OAuth 2.0 Authorization Framework for further details on the https://tools.ietf.org/html/rfc6749#section-1.3.1[Authorization Code] grant.
A request with the base path `/oauth2/authorization/okta` will initiate the Authorization Request redirect by the `OAuth2AuthorizationRequestRedirectWebFilter` and ultimately start the Authorization Code grant flow.
[NOTE]
====
The `AuthorizationCodeReactiveOAuth2AuthorizedClientProvider` is an implementation of `ReactiveOAuth2AuthorizedClientProvider` for the Authorization Code grant,
which also initiates the Authorization Request redirect by the `OAuth2AuthorizationRequestRedirectWebFilter`.
====
If the OAuth 2.0 Client is a https://tools.ietf.org/html/rfc6749#section-2.1[Public Client], then configure the OAuth 2.0 Client registration as follows:
@ -74,7 +80,9 @@ If the client is running in an untrusted environment (eg. native application or
@@ -74,7 +80,9 @@ If the client is running in an untrusted environment (eg. native application or
. `client-authentication-method` is set to "none" (`ClientAuthenticationMethod.NONE`)
[TIP]
====
If the OAuth 2.0 Provider supports PKCE for https://tools.ietf.org/html/rfc6749#section-2.1[Confidential Clients], you may (optionally) configure it using `DefaultServerOAuth2AuthorizationRequestResolver.setAuthorizationRequestCustomizer(OAuth2AuthorizationRequestCustomizers.withPkce())`.
====
[[oauth2-client-authorization-code-redirect-uri]]
[[oauth2Client-auth-code-redirect-uri]]The `DefaultServerOAuth2AuthorizationRequestResolver` also supports `URI` template variables for the `redirect-uri` using `UriComponentsBuilder`.
`+{baseUrl}+` resolves to `+{baseScheme}://{baseHost}{basePort}{basePath}+`
====
Configuring the `redirect-uri` with `URI` template variables is especially useful when the OAuth 2.0 Client is running behind a xref:features/exploits/http.adoc#http-proxy-server[Proxy Server].
This ensures that the `X-Forwarded-*` headers are used when expanding the `redirect-uri`.
@ -224,7 +234,9 @@ The preceding example shows the common use case of adding a custom parameter on
@@ -224,7 +234,9 @@ The preceding example shows the common use case of adding a custom parameter on
Alternatively, if your requirements are more advanced, you can take full control in building the Authorization Request URI by simply overriding the `OAuth2AuthorizationRequest.authorizationRequestUri` property.
[TIP]
====
`OAuth2AuthorizationRequest.Builder.build()` constructs the `OAuth2AuthorizationRequest.authorizationRequestUri`, which represents the Authorization Request URI including all query parameters using the `application/x-www-form-urlencoded` format.
====
The following example shows a variation of `authorizationRequestCustomizer()` from the preceding example, and instead overrides the `OAuth2AuthorizationRequest.authorizationRequestUri` property.
@ -263,7 +275,9 @@ private fun authorizationRequestCustomizer(): Consumer<OAuth2AuthorizationReques
@@ -263,7 +275,9 @@ private fun authorizationRequestCustomizer(): Consumer<OAuth2AuthorizationReques
The `ServerAuthorizationRequestRepository` is responsible for the persistence of the `OAuth2AuthorizationRequest` from the time the Authorization Request is initiated to the time the Authorization Response is received (the callback).
[TIP]
====
The `OAuth2AuthorizationRequest` is used to correlate and validate the Authorization Response.
====
The default implementation of `ServerAuthorizationRequestRepository` is `WebSessionOAuth2ServerAuthorizationRequestRepository`, which stores the `OAuth2AuthorizationRequest` in the `WebSession`.
@ -318,7 +332,9 @@ class OAuth2ClientSecurityConfig {
@@ -318,7 +332,9 @@ class OAuth2ClientSecurityConfig {
=== Requesting an Access Token
[NOTE]
====
Please refer to the https://tools.ietf.org/html/rfc6749#section-4.1.3[Access Token Request/Response] protocol flow for the Authorization Code grant.
====
The default implementation of `ReactiveOAuth2AccessTokenResponseClient` for the Authorization Code grant is `WebClientReactiveAuthorizationCodeTokenResponseClient`, which uses a `WebClient` for exchanging an authorization code for an access token at the Authorization Server’s Token Endpoint.
@ -400,13 +416,17 @@ class OAuth2ClientSecurityConfig {
@@ -400,13 +416,17 @@ class OAuth2ClientSecurityConfig {
Please refer to the OAuth 2.0 Authorization Framework for further details on the https://tools.ietf.org/html/rfc6749#section-1.5[Refresh Token].
====
[[oauth2-client-refresh-token-access-token]]
=== Refreshing an Access Token
[NOTE]
====
Please refer to the https://tools.ietf.org/html/rfc6749#section-6[Access Token Request/Response] protocol flow for the Refresh Token grant.
====
The default implementation of `ReactiveOAuth2AccessTokenResponseClient` for the Refresh Token grant is `WebClientReactiveRefreshTokenTokenResponseClient`, which uses a `WebClient` when refreshing an access token at the Authorization Server’s Token Endpoint.
`ReactiveOAuth2AuthorizedClientProviderBuilder.builder().refreshToken()` configures a `RefreshTokenReactiveOAuth2AuthorizedClientProvider`,
which is an implementation of a `ReactiveOAuth2AuthorizedClientProvider` for the Refresh Token grant.
====
The `OAuth2RefreshToken` may optionally be returned in the Access Token Response for the `authorization_code` and `password` grant types.
If the `OAuth2AuthorizedClient.getRefreshToken()` is available and the `OAuth2AuthorizedClient.getAccessToken()` is expired, it will automatically be refreshed by the `RefreshTokenReactiveOAuth2AuthorizedClientProvider`.
@ -474,13 +496,17 @@ If the `OAuth2AuthorizedClient.getRefreshToken()` is available and the `OAuth2Au
@@ -474,13 +496,17 @@ If the `OAuth2AuthorizedClient.getRefreshToken()` is available and the `OAuth2Au
Please refer to the OAuth 2.0 Authorization Framework for further details on the https://tools.ietf.org/html/rfc6749#section-1.3.4[Client Credentials] grant.
====
[[oauth2-client-client-credentials-access-token]]
=== Requesting an Access Token
[NOTE]
====
Please refer to the https://tools.ietf.org/html/rfc6749#section-4.4.2[Access Token Request/Response] protocol flow for the Client Credentials grant.
====
The default implementation of `ReactiveOAuth2AccessTokenResponseClient` for the Client Credentials grant is `WebClientReactiveClientCredentialsTokenResponseClient`, which uses a `WebClient` when requesting an access token at the Authorization Server’s Token Endpoint.
`ReactiveOAuth2AuthorizedClientProviderBuilder.builder().clientCredentials()` configures a `ClientCredentialsReactiveOAuth2AuthorizedClientProvider`,
which is an implementation of a `ReactiveOAuth2AuthorizedClientProvider` for the Client Credentials grant.
====
`ReactiveOAuth2AuthorizedClientProviderBuilder.builder().clientCredentials()` configures a `ClientCredentialsReactiveOAuth2AuthorizedClientProvider`, which is an implementation of a `ReactiveOAuth2AuthorizedClientProvider` for the Client Credentials grant.
@ -662,20 +689,26 @@ class OAuth2ClientController {
@@ -662,20 +689,26 @@ class OAuth2ClientController {
======
[NOTE]
====
`ServerWebExchange` is an OPTIONAL attribute.
If not provided, it will be obtained from the https://projectreactor.io/docs/core/release/reference/#context[Reactor's Context] via the key `ServerWebExchange.class`.
Please refer to the OAuth 2.0 Authorization Framework for further details on the https://tools.ietf.org/html/rfc6749#section-1.3.3[Resource Owner Password Credentials] grant.
====
[[oauth2-client-password-access-token]]
=== Requesting an Access Token
[NOTE]
====
Please refer to the https://tools.ietf.org/html/rfc6749#section-4.3.2[Access Token Request/Response] protocol flow for the Resource Owner Password Credentials grant.
====
The default implementation of `ReactiveOAuth2AccessTokenResponseClient` for the Resource Owner Password Credentials grant is `WebClientReactivePasswordTokenResponseClient`, which uses a `WebClient` when requesting an access token at the Authorization Server’s Token Endpoint.
@ -910,20 +945,26 @@ class OAuth2ClientController {
@@ -910,20 +945,26 @@ class OAuth2ClientController {
======
[NOTE]
====
`ServerWebExchange` is an OPTIONAL attribute.
If not provided, it will be obtained from the https://projectreactor.io/docs/core/release/reference/#context[Reactor's Context] via the key `ServerWebExchange.class`.
====
[[oauth2-client-jwt-bearer]]
== [[oauth2Client-jwt-bearer-grant]]JWT Bearer
[NOTE]
====
Please refer to JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants for further details on the https://datatracker.ietf.org/doc/html/rfc7523[JWT Bearer] grant.
====
[[oauth2-client-jwt-bearer-access-token]]
=== Requesting an Access Token
[NOTE]
====
Please refer to the https://datatracker.ietf.org/doc/html/rfc7523#section-2.1[Access Token Request/Response] protocol flow for the JWT Bearer grant.
====
The default implementation of `ReactiveOAuth2AccessTokenResponseClient` for the JWT Bearer grant is `WebClientReactiveJwtBearerTokenResponseClient`, which uses a `WebClient` when requesting an access token at the Authorization Server’s Token Endpoint.
@ -1108,22 +1149,30 @@ class OAuth2ResourceServerController {
@@ -1108,22 +1149,30 @@ class OAuth2ResourceServerController {
======
[NOTE]
====
`JwtBearerReactiveOAuth2AuthorizedClientProvider` resolves the `Jwt` assertion via `OAuth2AuthorizationContext.getPrincipal().getPrincipal()` by default, hence the use of `JwtAuthenticationToken` in the preceding example.
====
[TIP]
====
If you need to resolve the `Jwt` assertion from a different source, you can provide `JwtBearerReactiveOAuth2AuthorizedClientProvider.setJwtAssertionResolver()` with a custom `Function<OAuth2AuthorizationContext, Mono<Jwt>>`.
Please refer to OAuth 2.0 Token Exchange for further details on the https://datatracker.ietf.org/doc/html/rfc8693[Token Exchange] grant.
====
[[oauth2-client-token-exchange-access-token]]
=== Requesting an Access Token
[NOTE]
====
Please refer to the https://datatracker.ietf.org/doc/html/rfc8693#section-2[Token Exchange Request and Response] protocol flow for the Token Exchange grant.
====
The default implementation of `ReactiveOAuth2AccessTokenResponseClient` for the Token Exchange grant is `WebClientReactiveTokenExchangeTokenResponseClient`, which uses a `WebClient` when requesting an access token at the Authorization Server’s Token Endpoint.
@ -1308,11 +1357,17 @@ class OAuth2ResourceServerController {
@@ -1308,11 +1357,17 @@ class OAuth2ResourceServerController {
======
[NOTE]
====
`TokenExchangeReactiveOAuth2AuthorizedClientProvider` resolves the subject token (as an `OAuth2Token`) via `OAuth2AuthorizationContext.getPrincipal().getPrincipal()` by default, hence the use of `JwtAuthenticationToken` in the preceding example.
An actor token is not resolved by default.
====
[TIP]
====
If you need to resolve the subject token from a different source, you can provide `TokenExchangeReactiveOAuth2AuthorizedClientProvider.setSubjectTokenResolver()` with a custom `Function<OAuth2AuthorizationContext, Mono<OAuth2Token>>`.
====
[TIP]
====
If you need to resolve an actor token, you can provide `TokenExchangeReactiveOAuth2AuthorizedClientProvider.setActorTokenResolver()` with a custom `Function<OAuth2AuthorizationContext, Mono<OAuth2Token>>`.
@ -227,7 +227,9 @@ fun webClient(authorizedClientManager: ReactiveOAuth2AuthorizedClientManager): W
@@ -227,7 +227,9 @@ fun webClient(authorizedClientManager: ReactiveOAuth2AuthorizedClientManager): W
======
[WARNING]
====
It is recommended to be cautious with this feature since all HTTP requests will receive the access token.
====
Alternatively, if `setDefaultClientRegistrationId("okta")` is configured with a valid `ClientRegistration`, the `OAuth2AccessToken` associated with the `OAuth2AuthorizedClient` is used.
@ -266,4 +268,6 @@ fun webClient(authorizedClientManager: ReactiveOAuth2AuthorizedClientManager): W
@@ -266,4 +268,6 @@ fun webClient(authorizedClientManager: ReactiveOAuth2AuthorizedClientManager): W
======
[WARNING]
====
It is recommended to be cautious with this feature since all HTTP requests will receive the access token.
Please refer to JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants for further details on https://datatracker.ietf.org/doc/html/rfc7523#section-2.2[JWT Bearer] Client Authentication.
====
The default implementation for JWT Bearer Client Authentication is `NimbusJwtClientAuthenticationParametersConverter`,
which is a `Converter` that customizes the Token Request parameters by adding
@ -97,13 +97,17 @@ As an alternative, you can use `ClientRegistrations.fromOidcIssuerLocation()` to
@@ -97,13 +97,17 @@ As an alternative, you can use `ClientRegistrations.fromOidcIssuerLocation()` to
The `ReactiveClientRegistrationRepository` serves as a repository for OAuth 2.0 / OpenID Connect 1.0 `ClientRegistration`(s).
[NOTE]
====
Client registration information is ultimately stored and owned by the associated Authorization Server.
This repository provides the ability to retrieve a sub-set of the primary client registration information, which is stored with the Authorization Server.
====
Spring Boot auto-configuration binds each of the properties under `spring.security.oauth2.client.registration._[registrationId]_` to an instance of `ClientRegistration` and then composes each of the `ClientRegistration` instance(s) within a `ReactiveClientRegistrationRepository`.
[NOTE]
====
The default implementation of `ReactiveClientRegistrationRepository` is `InMemoryReactiveClientRegistrationRepository`.
====
The auto-configuration also registers the `ReactiveClientRegistrationRepository` as a `@Bean` in the `ApplicationContext` so that it is available for dependency-injection, if needed by the application.
@ -213,15 +217,19 @@ class OAuth2ClientController {
@@ -213,15 +217,19 @@ class OAuth2ClientController {
======
[NOTE]
====
Spring Boot auto-configuration registers an `ServerOAuth2AuthorizedClientRepository` and/or `ReactiveOAuth2AuthorizedClientService` `@Bean` in the `ApplicationContext`.
However, the application may choose to override and register a custom `ServerOAuth2AuthorizedClientRepository` or `ReactiveOAuth2AuthorizedClientService` `@Bean`.
====
The default implementation of `ReactiveOAuth2AuthorizedClientService` is `InMemoryReactiveOAuth2AuthorizedClientService`, which stores `OAuth2AuthorizedClient`(s) in-memory.
Alternatively, the R2DBC implementation `R2dbcReactiveOAuth2AuthorizedClientService` may be configured for persisting `OAuth2AuthorizedClient`(s) in a database.
[NOTE]
====
`R2dbcReactiveOAuth2AuthorizedClientService` depends on the table definition described in xref:servlet/appendix/database-schema.adoc#dbschema-oauth2-client[ OAuth 2.0 Client Schema].
@ -81,7 +81,9 @@ If the client is running in an untrusted environment (such as a native applicati
@@ -81,7 +81,9 @@ If the client is running in an untrusted environment (such as a native applicati
. `client-authentication-method` is set to `none` (`ClientAuthenticationMethod.NONE`)
[TIP]
====
If the OAuth 2.0 Provider supports PKCE for https://tools.ietf.org/html/rfc6749#section-2.1[Confidential Clients], you may (optionally) configure it using `DefaultOAuth2AuthorizationRequestResolver.setAuthorizationRequestCustomizer(OAuth2AuthorizationRequestCustomizers.withPkce())`.
====
[[oauth2-client-authorization-code-redirect-uri]]
[[oauth2Client-auth-code-redirect-uri]]The `DefaultOAuth2AuthorizationRequestResolver` also supports `URI` template variables for the `redirect-uri` by using `UriComponentsBuilder`.
Whether you customize `RestClientRefreshTokenTokenResponseClient` or provide your own implementation of `OAuth2AccessTokenResponseClient`, you can configure it using the `OAuth2AuthorizedClientProviderBuilder` (as an alternative to <<oauth2-client-refresh-token-access-token-response-client-bean,publishing a bean>>) as follows:
.Access Token Response Configuration via Builder
[tabs]
======
Java::
@ -554,7 +557,7 @@ Please refer to the OAuth 2.0 Authorization Framework for further details on the
@@ -554,7 +557,7 @@ Please refer to the OAuth 2.0 Authorization Framework for further details on the
[NOTE]
====
See the OAuth 2.0 Authorization Framework for further details on the https://tools.ietf.org/html/rfc6749#section-1.3.4[Client Credentials] grant.
See the https://tools.ietf.org/html/rfc6749#section-4.4.2[Access Token Request/Response] protocol flow for the Client Credentials grant.
====
There are two implementations of `OAuth2AccessTokenResponseClient` that can be used to make HTTP requests to the Token Endpoint in order to obtain an access token for the Client Credentials grant:
Whether you customize `RestClientClientCredentialsTokenResponseClient` or provide your own implementation of `OAuth2AccessTokenResponseClient`, you can configure it using the `OAuth2AuthorizedClientProviderBuilder` (as an alternative to <<oauth2-client-client-credentials-access-token-response-client-bean,publishing a bean>>) as follows:
.Access Token Response Configuration via Builder
[tabs]
======
Java::
@ -861,6 +865,7 @@ It uses an `OAuth2ErrorHttpMessageConverter` to convert the OAuth 2.0 Error para
@@ -861,6 +865,7 @@ It uses an `OAuth2ErrorHttpMessageConverter` to convert the OAuth 2.0 Error para
Whether you customize `DefaultPasswordTokenResponseClient` or provide your own implementation of `OAuth2AccessTokenResponseClient`, you need to configure it as follows:
Whether you customize `RestClientJwtBearerTokenResponseClient` or provide your own implementation of `OAuth2AccessTokenResponseClient`, you can configure it using the `OAuth2AuthorizedClientProviderBuilder` (as an alternative to <<oauth2-client-jwt-bearer-access-token-response-client-bean,publishing a bean>>) as follows:
.Access Token Response Configuration via Builder
[tabs]
======
Java::
@ -1301,10 +1307,14 @@ class OAuth2ResourceServerController {
@@ -1301,10 +1307,14 @@ class OAuth2ResourceServerController {
======
[NOTE]
====
`JwtBearerOAuth2AuthorizedClientProvider` resolves the `Jwt` assertion via `OAuth2AuthorizationContext.getPrincipal().getPrincipal()` by default, hence the use of `JwtAuthenticationToken` in the preceding example.
====
[TIP]
====
If you need to resolve the `Jwt` assertion from a different source, you can provide `JwtBearerOAuth2AuthorizedClientProvider.setJwtAssertionResolver()` with a custom `Function<OAuth2AuthorizationContext, Jwt>`.
Whether you customize `RestClientTokenExchangeTokenResponseClient` or provide your own implementation of `OAuth2AccessTokenResponseClient`, you can configure it using the `OAuth2AuthorizedClientProviderBuilder` (as an alternative to <<oauth2-client-token-exchange-access-token-response-client-bean,publishing a bean>>) as follows:
.Access Token Response Configuration via Builder
[tabs]
======
Java::
@ -1517,11 +1528,17 @@ class OAuth2ResourceServerController {
@@ -1517,11 +1528,17 @@ class OAuth2ResourceServerController {
======
[NOTE]
====
`TokenExchangeOAuth2AuthorizedClientProvider` resolves the subject token (as an `OAuth2Token`) via `OAuth2AuthorizationContext.getPrincipal().getPrincipal()` by default, hence the use of `JwtAuthenticationToken` in the preceding example.
An actor token is not resolved by default.
====
[TIP]
====
If you need to resolve the subject token from a different source, you can provide `TokenExchangeOAuth2AuthorizedClientProvider.setSubjectTokenResolver()` with a custom `Function<OAuth2AuthorizationContext, OAuth2Token>`.
====
[TIP]
====
If you need to resolve an actor token, you can provide `TokenExchangeOAuth2AuthorizedClientProvider.setActorTokenResolver()` with a custom `Function<OAuth2AuthorizationContext, OAuth2Token>`.
Please refer to JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants for further details on https://datatracker.ietf.org/doc/html/rfc7523#section-2.2[JWT Bearer] Client Authentication.
====
The default implementation for JWT Bearer Client Authentication is `NimbusJwtClientAuthenticationParametersConverter`,
which is a `Converter` that customizes the Token Request parameters by adding
@ -96,7 +100,7 @@ a signed JSON Web Token (JWS) in the `client_assertion` parameter.
@@ -96,7 +100,7 @@ a signed JSON Web Token (JWS) in the `client_assertion` parameter.
The `java.security.PrivateKey` or `javax.crypto.SecretKey` used for signing the JWS
is supplied by the `com.nimbusds.jose.jwk.JWK` resolver associated with `NimbusJwtClientAuthenticationParametersConverter`.
The JWT produced by `NimbusJwtClientAuthenticationParametersConverter` contains the `iss`, `sub`, `aud`, `jti`, `iat` and `exp` claims by default. You can customize the headers and/or claims by providing a `Consumer<NimbusJwtClientAuthenticationParametersConverter.JwtClientAuthenticationContext<T>>` to `setJwtClientAssertionCustomizer()`. The following example shows how to customize claims of the JWT:
There are two options for customizing request parameters by providing a `Converter<{grant-request}, MultiValueMap<String, String>>`:
There are three options for customizing request parameters:
* Add additional parameters by calling `addParametersConverter(...)`
* Override parameters by calling `setParametersConverter(...)`
* Add additional parameters by calling `addParametersConverter()`
* Override parameters by calling `setParametersConverter()`
* Fully customize parameters by calling `setParametersCustomizer()`
[NOTE]
====
Using `setParametersConverter()` does not fully customize parameters because it would require the user to provide all default parameters themselves.
Default parameters are always provided, but can be fully customized or omitted by providing a `Consumer<MultiValueMap<String, String>>` to `setParametersCustomizer(...)`.
Default parameters are always provided, but can be fully customized or omitted by calling `setParametersCustomizer()`.
====
You can include additional parameters without affecting the default parameters added to every request using `addParametersConverter()`.
`OAuth2AccessTokenResponseHttpMessageConverter` is an `HttpMessageConverter` for an OAuth 2.0 Access Token Response.
You can provide `setAccessTokenResponseConverter()` with a custom `Converter<Map<String, Object>, OAuth2AccessTokenResponse>` that is used for converting the OAuth 2.0 Access Token Response parameters to an `OAuth2AccessTokenResponse`.
You can customize the conversion of Token Response parameters to an `OAuth2AccessTokenResponse` by calling `setAccessTokenResponseConverter()`.
The default implementation is `DefaultMapOAuth2AccessTokenResponseConverter`.
`OAuth2ErrorResponseErrorHandler` is a `ResponseErrorHandler` that can handle an OAuth 2.0 Error, such as `400 Bad Request`.
It uses an `OAuth2ErrorHttpMessageConverter` for converting the OAuth 2.0 Error parameters to an `OAuth2Error`.
You can customize the conversion of Token Response parameters to an `OAuth2Error` by calling `setErrorConverter()`.
[TIP]
====
@ -307,6 +315,8 @@ Spring MVC `FormHttpMessageConverter` is required, as it is used when sending th
@@ -307,6 +315,8 @@ Spring MVC `FormHttpMessageConverter` is required, as it is used when sending th