OAuth 2.0 Client features of Spring Security 5.2.x do not support RestTemplate, but only WebClient. See Spring Security Reference:
HTTP Client support
WebClientintegration for Servlet Environments (for requesting
protected resources)
In addition, RestTemplate will be deprecated in a future version. See RestTemplate javadoc:
NOTE: As of 5.0, the non-blocking, reactive
org.springframework.web.reactive.client.WebClientoffers a modern
alternative to theRestTemplatewith efficient support for both sync
and async, as well as streaming scenarios. TheRestTemplatewill be
deprecated in a future version and will not have major new features
added going forward. See theWebClientsection of the Spring Framework
reference documentation for more details and example code.
Therefore, the best solution would be to abandon RestTemplate in favor of WebClient.
Using WebClient for Client Credentials Flow
Configure client registration and provider either programmatically or using Spring Boot auto-configuration:
spring:
security:
oauth2:
client:
registration:
custom:
client-id: clientId
client-secret: clientSecret
authorization-grant-type: client_credentials
provider:
custom:
token-uri: http://localhost:8081/oauth/token
…and the OAuth2AuthorizedClientManager @Bean:
@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;
}
Configure the WebClient instance to use ServerOAuth2AuthorizedClientExchangeFilterFunction with the provided OAuth2AuthorizedClientManager:
@Bean
WebClient webClient(OAuth2AuthorizedClientManager authorizedClientManager) {
ServletOAuth2AuthorizedClientExchangeFilterFunction oauth2Client =
new ServletOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager);
oauth2Client.setDefaultClientRegistrationId("custom");
return WebClient.builder()
.apply(oauth2Client.oauth2Configuration())
.build();
}
Now, if you try to make a request using this WebClient instance, it will first request a token from the authorization server and include it in the request.