Skip to content

Commit 5aa3772

Browse files
committed
Add ref doc for client_credentials grant
Fixes gh-6206
1 parent 8aa55fe commit 5aa3772

File tree

1 file changed

+155
-0
lines changed

1 file changed

+155
-0
lines changed

docs/manual/src/docs/asciidoc/_includes/servlet/preface/oauth2-client.adoc

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ The following sections will go into more detail on the core components used by O
8181
** <<oauth2Client-authorized-manager-provider, OAuth2AuthorizedClientManager / OAuth2AuthorizedClientProvider>>
8282
* <<oauth2Client-auth-grant-support>>
8383
** <<oauth2Client-auth-code-grant, Authorization Code>>
84+
** <<oauth2Client-client-creds-grant, Client Credentials>>
8485
* <<oauth2Client-additional-features>>
8586
** <<oauth2Client-registered-authorized-client, Resolving an Authorized Client>>
8687

@@ -551,6 +552,160 @@ public class OAuth2ClientSecurityConfig extends WebSecurityConfigurerAdapter {
551552
----
552553

553554

555+
[[oauth2Client-client-creds-grant]]
556+
==== Client Credentials
557+
558+
[NOTE]
559+
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.
560+
561+
562+
===== Requesting an Access Token
563+
564+
[NOTE]
565+
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.
566+
567+
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.
568+
569+
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.
570+
571+
572+
===== Customizing the Access Token Request
573+
574+
If you need to customize the pre-processing of the Token Request, you can provide `DefaultClientCredentialsTokenResponseClient.setRequestEntityConverter()` with a custom `Converter<OAuth2ClientCredentialsGrantRequest, RequestEntity<?>>`.
575+
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].
576+
However, providing a custom `Converter`, would allow you to extend the standard Token Request and add custom parameter(s).
577+
578+
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.
579+
580+
581+
===== Customizing the Access Token Response
582+
583+
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`.
584+
The default `RestOperations` is configured as follows:
585+
586+
[source,java]
587+
----
588+
RestTemplate restTemplate = new RestTemplate(Arrays.asList(
589+
new FormHttpMessageConverter(),
590+
new OAuth2AccessTokenResponseHttpMessageConverter()));
591+
592+
restTemplate.setErrorHandler(new OAuth2ErrorResponseErrorHandler());
593+
----
594+
595+
TIP: Spring MVC `FormHttpMessageConverter` is required as it's used when sending the OAuth 2.0 Access Token Request.
596+
597+
`OAuth2AccessTokenResponseHttpMessageConverter` is a `HttpMessageConverter` for an OAuth 2.0 Access Token Response.
598+
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`.
599+
600+
`OAuth2ErrorResponseErrorHandler` is a `ResponseErrorHandler` that can handle an OAuth 2.0 Error, eg. 400 Bad Request.
601+
It uses an `OAuth2ErrorHttpMessageConverter` for converting the OAuth 2.0 Error parameters to an `OAuth2Error`.
602+
603+
Whether you customize `DefaultClientCredentialsTokenResponseClient` or provide your own implementation of `OAuth2AccessTokenResponseClient`, you'll need to configure it as shown in the following example:
604+
605+
[source,java]
606+
----
607+
// Customize
608+
OAuth2AccessTokenResponseClient<OAuth2ClientCredentialsGrantRequest> clientCredentialsTokenResponseClient = ...
609+
610+
OAuth2AuthorizedClientProvider authorizedClientProvider =
611+
OAuth2AuthorizedClientProviderBuilder.builder()
612+
.clientCredentials(configurer -> configurer.accessTokenResponseClient(clientCredentialsTokenResponseClient))
613+
.build();
614+
615+
...
616+
617+
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
618+
----
619+
620+
[NOTE]
621+
`OAuth2AuthorizedClientProviderBuilder.builder().clientCredentials()` configures a `ClientCredentialsOAuth2AuthorizedClientProvider`,
622+
which is an implementation of an `OAuth2AuthorizedClientProvider` for the Client Credentials grant.
623+
624+
===== Using the Access Token
625+
626+
Given the following Spring Boot 2.x properties for an OAuth 2.0 Client registration:
627+
628+
[source,yaml]
629+
----
630+
spring:
631+
security:
632+
oauth2:
633+
client:
634+
registration:
635+
okta:
636+
client-id: okta-client-id
637+
client-secret: okta-client-secret
638+
authorization-grant-type: client_credentials
639+
scope: read, write
640+
provider:
641+
okta:
642+
token-uri: https://dev-1234.oktapreview.com/oauth2/v1/token
643+
----
644+
645+
...and the `OAuth2AuthorizedClientManager` `@Bean`:
646+
647+
[source,java]
648+
----
649+
@Bean
650+
public OAuth2AuthorizedClientManager authorizedClientManager(
651+
ClientRegistrationRepository clientRegistrationRepository,
652+
OAuth2AuthorizedClientRepository authorizedClientRepository) {
653+
654+
OAuth2AuthorizedClientProvider authorizedClientProvider =
655+
OAuth2AuthorizedClientProviderBuilder.builder()
656+
.clientCredentials()
657+
.build();
658+
659+
DefaultOAuth2AuthorizedClientManager authorizedClientManager =
660+
new DefaultOAuth2AuthorizedClientManager(
661+
clientRegistrationRepository, authorizedClientRepository);
662+
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
663+
664+
return authorizedClientManager;
665+
}
666+
----
667+
668+
[NOTE]
669+
Spring Boot 2.x auto-configuration registers an `OAuth2AuthorizedClientManager` `@Bean` in the `ApplicationContext`.
670+
671+
You may obtain the `OAuth2AccessToken` as follows:
672+
673+
[source,java]
674+
----
675+
@Controller
676+
public class OAuth2ClientController {
677+
678+
@Autowired
679+
private OAuth2AuthorizedClientManager authorizedClientManager;
680+
681+
@GetMapping("/")
682+
public String index(Authentication authentication,
683+
HttpServletRequest servletRequest,
684+
HttpServletResponse servletResponse) {
685+
686+
OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest.withClientRegistrationId("okta")
687+
.principal(authentication)
688+
.attributes(attrs -> {
689+
attrs.put(HttpServletRequest.class.getName(), servletRequest);
690+
attrs.put(HttpServletResponse.class.getName(), servletResponse);
691+
})
692+
.build();
693+
OAuth2AuthorizedClient authorizedClient = this.authorizedClientManager.authorize(authorizeRequest);
694+
695+
OAuth2AccessToken accessToken = authorizedClient.getAccessToken();
696+
697+
...
698+
699+
return "index";
700+
}
701+
}
702+
----
703+
704+
[NOTE]
705+
`HttpServletRequest` and `HttpServletResponse` are both OPTIONAL attributes.
706+
If not provided, it will default to `ServletRequestAttributes` using `RequestContextHolder.getRequestAttributes()`.
707+
708+
554709
[[oauth2Client-additional-features]]
555710
=== Additional Features
556711

0 commit comments

Comments
 (0)