Polish OAuth2 docs

This commit is contained in:
Steve Riesenberg 2024-10-28 12:28:24 -05:00
parent d5cb41156c
commit ea5bc28773
No known key found for this signature in database
GPG Key ID: 3D0169B18AB8F0A9
10 changed files with 142 additions and 32 deletions

View File

@ -7,13 +7,17 @@ This section describes Spring Security's support for authorization grants.
== [[oauth2Client-auth-code-grant]]Authorization Code
[NOTE]
====
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.
====
[[oauth2-client-authorization-code-authorization]]
=== Obtaining Authorization
[NOTE]
====
Please refer to the https://tools.ietf.org/html/rfc6749#section-4.1.1[Authorization Request/Response] protocol flow for the Authorization Code grant.
====
[[oauth2-client-authorization-code-authorization-request]]
=== Initiating the Authorization Request
@ -47,8 +51,10 @@ spring:
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
. `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`.
@ -95,7 +103,9 @@ spring:
----
[NOTE]
====
`+{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
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
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 {
=== 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 Servers Token Endpoint.
@ -400,13 +416,17 @@ class OAuth2ClientSecurityConfig {
== [[oauth2Client-refresh-token-grant]]Refresh Token
[NOTE]
====
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 Servers Token Endpoint.
@ -464,8 +484,10 @@ authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider)
======
[NOTE]
====
`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
== [[oauth2Client-client-creds-grant]]Client Credentials
[NOTE]
====
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 Servers Token Endpoint.
@ -536,8 +562,9 @@ authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider)
======
[NOTE]
`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.
====
[[oauth2-client-client-credentials-authorized-client-manager]]
=== Using the Access Token
@ -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`.
====
[[oauth2-client-password]]
== [[oauth2Client-password-grant]]Resource Owner Password Credentials
[NOTE]
====
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 Servers Token Endpoint.
@ -738,8 +771,10 @@ authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider)
======
[NOTE]
====
`ReactiveOAuth2AuthorizedClientProviderBuilder.builder().password()` configures a `PasswordReactiveOAuth2AuthorizedClientProvider`,
which is an implementation of a `ReactiveOAuth2AuthorizedClientProvider` for the Resource Owner Password Credentials grant.
====
[[oauth2-client-password-authorized-client-manager]]
=== Using the Access Token
@ -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 Servers Token Endpoint.
@ -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>>`.
====
[[oauth2-client-token-exchange]]
== [[oauth2Client-token-exchange-grant]]Token Exchange
[NOTE]
====
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 Servers Token Endpoint.
@ -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>>`.
====

View File

@ -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
======
[WARNING]
====
It is recommended to be cautious with this feature since all HTTP requests will receive the access token.
====

View File

@ -82,7 +82,9 @@ spring:
== [[oauth2Client-jwt-bearer-auth]]JWT Bearer
[NOTE]
====
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
@ -290,5 +292,7 @@ spring:
----
[NOTE]
====
Public Clients are supported using https://tools.ietf.org/html/rfc7636[Proof Key for Code Exchange] (PKCE).
PKCE will automatically be used when `client-authentication-method` is set to "none" (`ClientAuthenticationMethod.NONE`).
====

View File

@ -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 {
======
[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].
====
[[oauth2Client-authorized-manager-provider]]

View File

@ -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`.
@ -494,6 +496,7 @@ include::partial$servlet/oauth2/client/rest-client-access-token-response-client.
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
[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:
@ -585,6 +588,7 @@ include::partial$servlet/oauth2/client/rest-client-access-token-response-client.
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
Whether you customize `DefaultPasswordTokenResponseClient` or provide your own implementation of `OAuth2AccessTokenResponseClient`, you need to configure it as follows:
.Access Token Response Configuration via Builder
[tabs]
======
Java::
@ -1134,6 +1139,7 @@ include::partial$servlet/oauth2/client/rest-client-access-token-response-client.
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 {
======
[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>`.
====
[[oauth2-client-token-exchange]]
== [[oauth2Client-token-exchange-grant]]Token Exchange
@ -1350,6 +1360,7 @@ include::partial$servlet/oauth2/client/rest-client-access-token-response-client.
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 {
======
[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>`.
====

View File

@ -1,7 +1,7 @@
[[oauth2-client-additional-features]]
= [[oauth2Client-additional-features]]Authorized Client Features
This section covers additional features provided by Spring Security for the OAuth2 client.
This section covers additional features provided by Spring Security for OAuth2 client.
[[oauth2-client-registered-authorized-client]]
== [[oauth2Client-registered-authorized-client]]Resolving an Authorized Client
@ -700,7 +700,9 @@ fun index(): String {
<1> `authentication()` is a `static` method in `ServletOAuth2AuthorizedClientExchangeFilterFunction`.
[WARNING]
====
It is recommended to be cautious with this feature since all HTTP requests will receive an access token bound to the provided principal.
====
[[oauth2-client-web-client-default-authorized-client]]
=== Defaulting the Authorized Client

View File

@ -1,9 +1,10 @@
[[oauth2-client-authentication]]
= [[oauth2Client-client-auth-support]]Client Authentication Support
[[oauth2-client-client-credentials-authentication]]
[[oauth2-client-authentication-client-credentials]]
== [[oauth2Client-client-credentials-auth]]Client Credentials
[[oauth2-client-authentication-client-credentials-client-secret-basic]]
=== Authenticate using `client_secret_basic`
Client Authentication with HTTP Basic is supported out of the box and no customization is necessary to enable it.
@ -62,6 +63,7 @@ tokenResponseClient.setRequestEntityConverter(requestEntityConverter)
----
======
[[oauth2-client-authentication-client-credentials-client-secret-post]]
=== Authenticate using `client_secret_post`
Client Authentication with client credentials included in the request-body is supported out of the box and no customization is necessary to enable it.
@ -83,11 +85,13 @@ spring:
...
----
[[oauth2-client-jwt-bearer-authentication]]
[[oauth2-client-authentication-jwt-bearer]]
== [[oauth2Client-jwt-bearer-auth]]JWT Bearer
[NOTE]
====
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.
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`.
[[oauth2-client-authentication-jwt-bearer-private-key-jwt]]
=== Authenticate using `private_key_jwt`
Given the following Spring Boot properties for an OAuth 2.0 Client registration:
@ -174,6 +178,7 @@ tokenResponseClient.setRequestEntityConverter(requestEntityConverter)
----
======
[[oauth2-client-authentication-jwt-bearer-client-secret-jwt]]
=== Authenticate using `client_secret_jwt`
Given the following Spring Boot properties for an OAuth 2.0 Client registration:
@ -250,6 +255,7 @@ tokenResponseClient.setRequestEntityConverter(requestEntityConverter)
----
======
[[oauth2-client-authentication-jwt-bearer-assertion]]
=== Customizing the JWT assertion
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:
@ -285,7 +291,7 @@ converter.setJwtClientAssertionCustomizer { context ->
----
======
[[oauth2-client-public-authentication]]
[[oauth2-client-authentication-public]]
== [[oauth2Client-public-auth]]Public Authentication
Public Client Authentication is supported out of the box and no customization is necessary to enable it.
@ -307,5 +313,7 @@ spring:
----
[NOTE]
====
Public Clients are supported using https://tools.ietf.org/html/rfc7636[Proof Key for Code Exchange] (PKCE).
PKCE will automatically be used when `client-authentication-method` is set to "none" (`ClientAuthenticationMethod.NONE`).
====

View File

@ -15,7 +15,7 @@ At a high-level, the core features available are:
* xref:servlet/oauth2/client/authorization-grants.adoc#oauth2-client-token-exchange[Token Exchange]
.Client Authentication support
* xref:servlet/oauth2/client/client-authentication.adoc#oauth2-client-jwt-bearer-authentication[JWT Bearer]
* xref:servlet/oauth2/client/client-authentication.adoc#oauth2-client-authentication-jwt-bearer[JWT Bearer]
.HTTP Client support (for requesting protected resources)
* xref:servlet/oauth2/client/authorized-clients.adoc#oauth2-client-rest-client[`RestClient` integration]

View File

@ -2059,7 +2059,7 @@ class SecurityConfig {
[[further-reading]]
== Further Reading
This preceding sections introduced Spring Security's support for OAuth2 with examples for common scenarios.
The preceding sections introduced Spring Security's support for OAuth2 with examples for common scenarios.
You can read more about OAuth2 Client and Resource Server in the following sections of the reference documentation:
* xref:servlet/oauth2/login/index.adoc[]

View File

@ -19,8 +19,8 @@ Kotlin::
[source,kotlin,role="secondary",subs="+attributes"]
----
@Bean
fun myAccessTokenResponseClient(): OAuth2AccessTokenResponseClient<{grant-type}> {
return new {class-name}()
fun accessTokenResponseClient(): OAuth2AccessTokenResponseClient<{grant-type}> {
return {class-name}()
}
----
======
@ -35,22 +35,22 @@ Choose from the following use cases to learn more:
* I want to <<oauth2-client-{section-id}-access-token-request-headers,customize headers of the Access Token request>>
* I want to <<oauth2-client-{section-id}-access-token-request-parameters,customize parameters of the Access Token request>>
* I want to <<oauth2-client-{section-id}-access-token-response,customize the instance of `RestClient` that is used>>
* I want to <<oauth2-client-{section-id}-access-token-response-rest-client,customize the instance of `RestClient` that is used>>
* I want to <<oauth2-client-{section-id}-access-token-response-parameters,customize parameters of the Access Token response>>
* I want to <<oauth2-client-{section-id}-access-token-response-errors,customize error handling of the Access Token response>>
[#oauth2-client-{section-id}-access-token-request]
== Customizing the Access Token Request
`{class-name}` provides hooks for customizing HTTP headers and request parameters of the Token Request.
`{class-name}` provides hooks for customizing HTTP headers and request parameters of the OAuth 2.0 Access Token Request.
[#oauth2-client-{section-id}-access-token-request-headers]
=== Customizing Request Headers
There are two options for customizing HTTP headers by providing a `Converter<{grant-request}, HttpHeaders>`:
There are two options for customizing HTTP headers:
* Add additional headers by calling `addHeadersConverter(...)`
* Fully customize headers by calling `setHeadersConverter(...)`
* Add additional headers by calling `addHeadersConverter()`
* Fully customize headers by calling `setHeadersConverter()`
You can include additional headers without affecting the default headers added to every request using `addHeadersConverter()`.
The following example adds a `User-Agent` header to the request when the `registrationId` is `spring`:
@ -64,11 +64,11 @@ Java::
----
{class-name} accessTokenResponseClient =
new {class-name}();
accessTokenResponseClient.addHeadersConverter((grantRequest) -> {
accessTokenResponseClient.addHeadersConverter(grantRequest -> {
ClientRegistration clientRegistration = grantRequest.getClientRegistration();
HttpHeaders headers = new HttpHeaders();
if (clientRegistration.getRegistrationId().equals("spring")) {
headers.set(HttpHeaders.USER_AGENT, "...");
headers.set(HttpHeaders.USER_AGENT, "my-user-agent");
}
return headers;
});
@ -83,7 +83,7 @@ accessTokenResponseClient.addHeadersConverter { grantRequest ->
val clientRegistration = grantRequest.getClientRegistration()
val headers = HttpHeaders()
if (clientRegistration.getRegistrationId() == "spring") {
headers[HttpHeaders.USER_AGENT] = "..."
headers[HttpHeaders.USER_AGENT] = "my-user-agent"
}
headers
}
@ -124,15 +124,16 @@ accessTokenResponseClient.setHeadersConverter(headersConverter)
[#oauth2-client-{section-id}-access-token-request-parameters]
=== Customizing Request Parameters
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()`.
@ -147,7 +148,7 @@ Java::
----
{class-name} accessTokenResponseClient =
new {class-name}();
accessTokenResponseClient.addParametersConverter((grantRequest) -> {
accessTokenResponseClient.addParametersConverter(grantRequest -> {
ClientRegistration clientRegistration = grantRequest.getClientRegistration();
MultiValueMap<String, String> parameters = new LinkedMultiValueMap<String, String>();
if (clientRegistration.getRegistrationId().equals("keycloak")) {
@ -185,7 +186,7 @@ Java::
----
{class-name} accessTokenResponseClient =
new {class-name}();
accessTokenResponseClient.setParametersConverter((grantRequest) -> {
accessTokenResponseClient.setParametersConverter(grantRequest -> {
ClientRegistration clientRegistration = grantRequest.getClientRegistration();
LinkedMultiValueMap<String, String> parameters = new LinkedMultiValueMap<>();
if (clientRegistration.getRegistrationId().equals("okta")) {
@ -230,7 +231,7 @@ Java::
----
{class-name} accessTokenResponseClient =
new {class-name}();
accessTokenResponseClient.setParametersCustomizer((parameters) -> {
accessTokenResponseClient.setParametersCustomizer(parameters -> {
if (parameters.containsKey(OAuth2ParameterNames.CLIENT_ASSERTION)) {
parameters.remove(OAuth2ParameterNames.CLIENT_ID);
}
@ -253,7 +254,12 @@ accessTokenResponseClient.setParametersCustomizer { parameters ->
[#oauth2-client-{section-id}-access-token-response]
== Customizing the Access Token Response
You can customize the Token Response by providing a pre-configured `RestClient` to `setRestClient(...)`.
`{class-name}` provides hooks for customizing response parameters and error handling of the OAuth 2.0 Access Token Response.
[#oauth2-client-{section-id}-access-token-response-rest-client]
=== Customizing the `WebClient`
You can customize the Token Response by providing a pre-configured `RestClient` to `setRestClient()`.
The default `RestClient` is configured as follows:
.Default `RestClient` Configuration
@ -264,7 +270,7 @@ Java::
[source,java,role="primary",subs="+attributes"]
----
RestClient restClient = RestClient.builder()
.messageConverters((messageConverters) -> {
.messageConverters(messageConverters -> {
messageConverters.clear();
messageConverters.add(new FormHttpMessageConverter());
messageConverters.add(new OAuth2AccessTokenResponseHttpMessageConverter());
@ -296,10 +302,12 @@ accessTokenResponseClient.setRestClient(restClient)
======
`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
====
[#oauth2-client-{section-id}-access-token-response-parameters]
=== Customizing Response Parameters
The following example provides a starting point for customizing the conversion of Token Response parameters to an `OAuth2AccessTokenResponse`:
.Customize Access Token Response Converter
@ -318,7 +328,7 @@ Java::
----
OAuth2AccessTokenResponseHttpMessageConverter accessTokenResponseMessageConverter =
new OAuth2AccessTokenResponseHttpMessageConverter();
accessTokenResponseMessageConverter.setAccessTokenResponseConverter((parameters) -> {
accessTokenResponseMessageConverter.setAccessTokenResponseConverter(parameters -> {
// ...
return OAuth2AccessTokenResponse.withToken("custom-token")
// ...
@ -341,6 +351,8 @@ accessTokenResponseMessageConverter.setAccessTokenResponseConverter { parameters
======
[#oauth2-client-{section-id}-access-token-response-errors]
=== Customizing Error Handling
The following example provides a starting point for customizing the conversion of Error parameters to an `OAuth2Error`:
.Customize Access Token Error Handler
@ -352,7 +364,7 @@ Java::
----
OAuth2ErrorHttpMessageConverter errorConverter =
new OAuth2ErrorHttpMessageConverter();
errorConverter.setErrorConverter((parameters) -> {
errorConverter.setErrorConverter(parameters -> {
// ...
return new OAuth2Error("custom-error", "custom description", "custom-uri");
});