|
@@ -81,6 +81,7 @@ The following sections will go into more detail on the core components used by O
|
|
** <<oauth2Client-authorized-manager-provider, OAuth2AuthorizedClientManager / OAuth2AuthorizedClientProvider>>
|
|
** <<oauth2Client-authorized-manager-provider, OAuth2AuthorizedClientManager / OAuth2AuthorizedClientProvider>>
|
|
* <<oauth2Client-auth-grant-support>>
|
|
* <<oauth2Client-auth-grant-support>>
|
|
** <<oauth2Client-auth-code-grant, Authorization Code>>
|
|
** <<oauth2Client-auth-code-grant, Authorization Code>>
|
|
|
|
+** <<oauth2Client-client-creds-grant, Client Credentials>>
|
|
* <<oauth2Client-additional-features>>
|
|
* <<oauth2Client-additional-features>>
|
|
** <<oauth2Client-registered-authorized-client, Resolving an Authorized Client>>
|
|
** <<oauth2Client-registered-authorized-client, Resolving an Authorized Client>>
|
|
|
|
|
|
@@ -551,6 +552,160 @@ public class OAuth2ClientSecurityConfig extends WebSecurityConfigurerAdapter {
|
|
----
|
|
----
|
|
|
|
|
|
|
|
|
|
|
|
+[[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.
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+===== 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 `OAuth2AccessTokenResponseClient` for the Client Credentials grant is `DefaultClientCredentialsTokenResponseClient`, which uses a `RestOperations` when requesting an access token at the Authorization Server’s Token Endpoint.
|
|
|
|
+
|
|
|
|
+The `DefaultClientCredentialsTokenResponseClient` is quite flexible as it allows you to customize the pre-processing of the Token Request and/or post-handling of the Token Response.
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+===== Customizing the Access Token Request
|
|
|
|
+
|
|
|
|
+If you need to customize the pre-processing of the Token Request, you can provide `DefaultClientCredentialsTokenResponseClient.setRequestEntityConverter()` with a custom `Converter<OAuth2ClientCredentialsGrantRequest, RequestEntity<?>>`.
|
|
|
|
+The default implementation `OAuth2ClientCredentialsRequestEntityConverter` builds a `RequestEntity` representation of a standard https://tools.ietf.org/html/rfc6749#section-4.4.2[OAuth 2.0 Access Token Request].
|
|
|
|
+However, providing a custom `Converter`, would allow you to extend the standard Token Request and add custom parameter(s).
|
|
|
|
+
|
|
|
|
+IMPORTANT: The custom `Converter` must return a valid `RequestEntity` representation of an OAuth 2.0 Access Token Request that is understood by the intended OAuth 2.0 Provider.
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+===== Customizing the Access Token Response
|
|
|
|
+
|
|
|
|
+On the other end, if you need to customize the post-handling of the Token Response, you will need to provide `DefaultClientCredentialsTokenResponseClient.setRestOperations()` with a custom configured `RestOperations`.
|
|
|
|
+The default `RestOperations` is configured as follows:
|
|
|
|
+
|
|
|
|
+[source,java]
|
|
|
|
+----
|
|
|
|
+RestTemplate restTemplate = new RestTemplate(Arrays.asList(
|
|
|
|
+ new FormHttpMessageConverter(),
|
|
|
|
+ new OAuth2AccessTokenResponseHttpMessageConverter()));
|
|
|
|
+
|
|
|
|
+restTemplate.setErrorHandler(new OAuth2ErrorResponseErrorHandler());
|
|
|
|
+----
|
|
|
|
+
|
|
|
|
+TIP: Spring MVC `FormHttpMessageConverter` is required as it's used when sending the OAuth 2.0 Access Token Request.
|
|
|
|
+
|
|
|
|
+`OAuth2AccessTokenResponseHttpMessageConverter` is a `HttpMessageConverter` for an OAuth 2.0 Access Token Response.
|
|
|
|
+You can provide `OAuth2AccessTokenResponseHttpMessageConverter.setTokenResponseConverter()` with a custom `Converter<Map<String, String>, OAuth2AccessTokenResponse>` that is used for converting the OAuth 2.0 Access Token Response parameters to an `OAuth2AccessTokenResponse`.
|
|
|
|
+
|
|
|
|
+`OAuth2ErrorResponseErrorHandler` is a `ResponseErrorHandler` that can handle an OAuth 2.0 Error, eg. 400 Bad Request.
|
|
|
|
+It uses an `OAuth2ErrorHttpMessageConverter` for converting the OAuth 2.0 Error parameters to an `OAuth2Error`.
|
|
|
|
+
|
|
|
|
+Whether you customize `DefaultClientCredentialsTokenResponseClient` or provide your own implementation of `OAuth2AccessTokenResponseClient`, you'll need to configure it as shown in the following example:
|
|
|
|
+
|
|
|
|
+[source,java]
|
|
|
|
+----
|
|
|
|
+// Customize
|
|
|
|
+OAuth2AccessTokenResponseClient<OAuth2ClientCredentialsGrantRequest> clientCredentialsTokenResponseClient = ...
|
|
|
|
+
|
|
|
|
+OAuth2AuthorizedClientProvider authorizedClientProvider =
|
|
|
|
+ OAuth2AuthorizedClientProviderBuilder.builder()
|
|
|
|
+ .clientCredentials(configurer -> configurer.accessTokenResponseClient(clientCredentialsTokenResponseClient))
|
|
|
|
+ .build();
|
|
|
|
+
|
|
|
|
+...
|
|
|
|
+
|
|
|
|
+authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
|
|
|
|
+----
|
|
|
|
+
|
|
|
|
+[NOTE]
|
|
|
|
+`OAuth2AuthorizedClientProviderBuilder.builder().clientCredentials()` configures a `ClientCredentialsOAuth2AuthorizedClientProvider`,
|
|
|
|
+which is an implementation of an `OAuth2AuthorizedClientProvider` for the Client Credentials grant.
|
|
|
|
+
|
|
|
|
+===== Using the Access Token
|
|
|
|
+
|
|
|
|
+Given the following Spring Boot 2.x properties for an OAuth 2.0 Client registration:
|
|
|
|
+
|
|
|
|
+[source,yaml]
|
|
|
|
+----
|
|
|
|
+spring:
|
|
|
|
+ security:
|
|
|
|
+ oauth2:
|
|
|
|
+ client:
|
|
|
|
+ registration:
|
|
|
|
+ okta:
|
|
|
|
+ client-id: okta-client-id
|
|
|
|
+ client-secret: okta-client-secret
|
|
|
|
+ authorization-grant-type: client_credentials
|
|
|
|
+ scope: read, write
|
|
|
|
+ provider:
|
|
|
|
+ okta:
|
|
|
|
+ token-uri: https://dev-1234.oktapreview.com/oauth2/v1/token
|
|
|
|
+----
|
|
|
|
+
|
|
|
|
+...and the `OAuth2AuthorizedClientManager` `@Bean`:
|
|
|
|
+
|
|
|
|
+[source,java]
|
|
|
|
+----
|
|
|
|
+@Bean
|
|
|
|
+public OAuth2AuthorizedClientManager authorizedClientManager(
|
|
|
|
+ ClientRegistrationRepository clientRegistrationRepository,
|
|
|
|
+ OAuth2AuthorizedClientRepository authorizedClientRepository) {
|
|
|
|
+
|
|
|
|
+ OAuth2AuthorizedClientProvider authorizedClientProvider =
|
|
|
|
+ OAuth2AuthorizedClientProviderBuilder.builder()
|
|
|
|
+ .clientCredentials()
|
|
|
|
+ .build();
|
|
|
|
+
|
|
|
|
+ DefaultOAuth2AuthorizedClientManager authorizedClientManager =
|
|
|
|
+ new DefaultOAuth2AuthorizedClientManager(
|
|
|
|
+ clientRegistrationRepository, authorizedClientRepository);
|
|
|
|
+ authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
|
|
|
|
+
|
|
|
|
+ return authorizedClientManager;
|
|
|
|
+}
|
|
|
|
+----
|
|
|
|
+
|
|
|
|
+[NOTE]
|
|
|
|
+Spring Boot 2.x auto-configuration registers an `OAuth2AuthorizedClientManager` `@Bean` in the `ApplicationContext`.
|
|
|
|
+
|
|
|
|
+You may obtain the `OAuth2AccessToken` as follows:
|
|
|
|
+
|
|
|
|
+[source,java]
|
|
|
|
+----
|
|
|
|
+@Controller
|
|
|
|
+public class OAuth2ClientController {
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ private OAuth2AuthorizedClientManager authorizedClientManager;
|
|
|
|
+
|
|
|
|
+ @GetMapping("/")
|
|
|
|
+ public String index(Authentication authentication,
|
|
|
|
+ HttpServletRequest servletRequest,
|
|
|
|
+ HttpServletResponse servletResponse) {
|
|
|
|
+
|
|
|
|
+ OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest.withClientRegistrationId("okta")
|
|
|
|
+ .principal(authentication)
|
|
|
|
+ .attributes(attrs -> {
|
|
|
|
+ attrs.put(HttpServletRequest.class.getName(), servletRequest);
|
|
|
|
+ attrs.put(HttpServletResponse.class.getName(), servletResponse);
|
|
|
|
+ })
|
|
|
|
+ .build();
|
|
|
|
+ OAuth2AuthorizedClient authorizedClient = this.authorizedClientManager.authorize(authorizeRequest);
|
|
|
|
+
|
|
|
|
+ OAuth2AccessToken accessToken = authorizedClient.getAccessToken();
|
|
|
|
+
|
|
|
|
+ ...
|
|
|
|
+
|
|
|
|
+ return "index";
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+----
|
|
|
|
+
|
|
|
|
+[NOTE]
|
|
|
|
+`HttpServletRequest` and `HttpServletResponse` are both OPTIONAL attributes.
|
|
|
|
+If not provided, it will default to `ServletRequestAttributes` using `RequestContextHolder.getRequestAttributes()`.
|
|
|
|
+
|
|
|
|
+
|
|
[[oauth2Client-additional-features]]
|
|
[[oauth2Client-additional-features]]
|
|
=== Additional Features
|
|
=== Additional Features
|
|
|
|
|