Auth0 Home Blog Docs

Audience not supported in Spring's @EnableOAuth2Client

spring-boot
client-credentials-g
spring-security

#1

We’re using Auth0 as Authorization Server in a micro services environment. Our batch application needs to connect to the main API through client credentials (machine-to-machine). We are using Spring’s RestTemplate and @EnableOAuth2Client to get an access_token and make calls to the Resource server. We’re using latest spring-boot (2.0.1.RELEASE). But, Auth0 needs the "audience"property filled and the ClientCredentialsResourceDetails() doesn’t have this property. So, I want to write an interceptor to add this property. Here’s the Auth0Config class:

@Configuration
@EnableOAuth2Client
public class OAuthConfig {

    private static final Logger LOGGER = LoggerFactory.getLogger(OAuthConfig.class);

    @Value("${planbatch.target.client_id}")
    private String oAuth2ClientId;

    @Value("${planbatch.target.client_secret}")
    private String oAuth2ClientSecret;

    @Value("${planbatch.target.access_token_uri}")
    private String accessTokenUri;

    @Value("${planbatch.target.audience}")
    private String audience;

    @Bean
    public RestTemplate oAuthRestTemplate() {

        ClientCredentialsResourceDetails resourceDetails = new ClientCredentialsResourceDetails();
        resourceDetails.setId("1");
        resourceDetails.setClientId(oAuth2ClientId);
        resourceDetails.setClientSecret(oAuth2ClientSecret);
        resourceDetails.setAccessTokenUri(accessTokenUri);
        resourceDetails.setClientAuthenticationScheme(AuthenticationScheme.form);

        OAuth2RestTemplate restTemplate = new OAuth2RestTemplate(resourceDetails);

        final List<ClientHttpRequestInterceptor> interceptors = new ArrayList<>();
        interceptors.add(new AddAudienceInterceptor(audience));
        restTemplate.setInterceptors(interceptors);
        return restTemplate;
    }
}

And here’s the interceptor:

public class AddAudienceInterceptor implements ClientHttpRequestInterceptor {
    
        private static final Logger LOGGER = LoggerFactory.getLogger(AddAudienceInterceptor.class);
    
        private String audience;
    
        public AddAudienceInterceptor(String audience) {
            this.audience = audience;
        }
    
        @Override
        public ClientHttpResponse intercept(HttpRequest httpRequest, byte[] bytes, ClientHttpRequestExecution clientHttpRequestExecution) throws IOException {
    
            if (bytes.length > 0) {
                ObjectMapper mapper = new ObjectMapper();
                Auth0ClientCredentials credentials = mapper.readValue(bytes, Auth0ClientCredentials.class);
                credentials.setAudience(audience);
                bytes = mapper.writeValueAsBytes(credentials);
            }
            return clientHttpRequestExecution.execute(httpRequest, bytes);
        }
    }

The problem is that the interceptor works on the calls to the ResourceServer but the goal is to intercept the calls to the AuthorizationServer (Auth0 in my case).

The body of the call to the AuthorizationServer is currently:

Body:
{ grant_type: 'client_credentials',
  client_id: 'my_client_id',
  client_secret: 'my_client_secret' }

What I need to achieve is:

Body:
{ grant_type: 'client_credentials',
  client_id: 'my_client_id',
  client_secret: 'my_client_secret',
  audience: 'my_audience' }

Anyone any idea how I can achieve this? Thanks for you help!