The client credentials grant type lets an application obtain an OAuth 2 access token with its own client credentials, without user authentication, consent, redirects, or authorization codes. It fits backend-to-backend communication, such as a scheduled process calling another service. section 13.3.3 section 16.2
The flow proceeds sequentially:
- Register the client with a client ID, client secret, client authentication method, grant type, and purpose-specific scope. section 14.3
- Send the client ID and secret to the authorization server’s token endpoint, commonly using HTTP Basic authentication. section 14.3
- Request the client credentials grant and an appropriate scope, then receive an access token if authentication succeeds. section 14.3 section 13.3.3
- Send the access token as a Bearer token when calling protected resource-server endpoints. section 13.3.3 section 16.2
With Spring Security, configure the client registration with the token URI, client credentials, CLIENT_CREDENTIALS grant, CLIENT_SECRET_BASIC authentication, and scopes. Enable OAuth 2 client support, then configure an OAuth2AuthorizedClientManager with a client-credentials provider. The manager executes the grant and supplies the token to application code. section 16.2 section 16.3
Spring token retrieval
A controller can create an OAuth2AuthorizeRequest with a client registration ID and principal, call clientManager.authorize(request), and return client.getAccessToken().getTokenValue(). A real application would normally use the obtained token in a proxy layer when sending a request to another service. section 16.2
Listing 14.8 Configuring a registered client for the client credentials grant type
@Bean
public RegisteredClientRepository registeredClientRepository() {
RegisteredClient registeredClient =
RegisteredClient.withId(UUID.randomUUID().toString())
.clientId("client")
.clientSecret("secret")
.clientAuthenticationMethod(
ClientAuthenticationMethod.CLIENT_SECRET_BASIC) #1
.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
.scope("CUSTOM") #2
.build();
return new InMemoryRegisteredClientRepository(registeredClient);
}
Inspect the registered-client configuration showing CLIENT_SECRET_BASIC authentication, the CLIENT_CREDENTIALS grant, and a dedicated scope. section 14.3




