I've been trying to figure out how to use spring-boot-starter-oauth2-client package to retrieve an oAuth token from an OpenID server.
I can configure the application.yml file with the appropriate settings, and see that the ReactiveClientRegistrationRepository
and ServerOAuth2AuthorizedClientRepository
beans are created properly.
I'm even able to create a ClientManager, although not entirely sure why this isn't done automatically by SpringBoot. But then, frankly, I am stumped as to how to get an OAuth2Client from the manager.
security:
oauth2:
client:
registration:
auth0:
client-id: MgqYHnr4p3wed9qKdzRu9G
client-secret: some_secret_code
provider:
auth0:
issuer-uri: https://dev-5cjo8.eu.auth0.com/
@Bean
public ReactiveOAuth2AuthorizedClientManager authorizedClientManager(final ReactiveClientRegistrationRepository clientRegistrationRepository,
final ServerOAuth2AuthorizedClientRepository authorizedClientRepository) {
ReactiveOAuth2AuthorizedClientProvider authorizedClientProvider = ReactiveOAuth2AuthorizedClientProviderBuilder.builder()
.clientCredentials()
.build();
DefaultReactiveOAuth2AuthorizedClientManager authorizedClientManager = new DefaultReactiveOAuth2AuthorizedClientManager(clientRegistrationRepository, authorizedClientRepository);
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
return authorizedClientManager;
}
I'm a bit perplexed as to what the next step would be. I am looking to use grant_type: client_credentials
and exchange the clientId/secret that are in the application.yml file for an AccessToken, but not sure how to accomplish this.
It would be fairly straightforward to send a request to the token_endpoint
using a RestTemplate and parsing the response, but I figure there must be a way to accomplish this using the OAuth2 lib.
How do I use the clientManager to get a client to authenticate using the token endpoint? Keep in mind that I am not looking to build a web-app, or retrieve a specific resource - I am just looking for the access token.
Countless hours of investigating later, I discovered that the DefaultReactiveOAuth2AuthorizedClientManager
is intended to be used within a request context. (see https://github.com/spring-projects/spring-security/issues/8444#issuecomment-621567261)
Accordingly, modifying the ClientManager bean to be defined as:
@Bean
public ReactiveOAuth2AuthorizedClientManager authorizedClientManager(final ReactiveClientRegistrationRepository clientRegistrationRepository,
final ReactiveOAuth2AuthorizedClientService clientService) {
ReactiveOAuth2AuthorizedClientProvider authorizedClientProvider = ReactiveOAuth2AuthorizedClientProviderBuilder.builder()
.clientCredentials()
.build();
AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager authorizedClientManager = new AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager(clientRegistrationRepository, clientService);
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
return authorizedClientManager;
}
allows for use of the client as follows:
public String getAccessToken(ReactiveOAuth2AuthorizedClientManager manager){
OAuth2AuthorizeRequest req = OAuth2AuthorizeRequest.withClientRegistrationId("auth0").principal("N/A").build();
OAuth2AuthorizedClient client = manager.authorize(req).block();
return client.getAccessToken().getTokenValue();
}