1
votes

We have the following client configuration for our oauth2 clients in place that worked quite well with spring boot 1.4.0:

@Configuration
@ConfigurationProperties(prefix = "pmc.oauth.client")
public class OAuthClientConfig {

@NotNull
private String scope;

@NotNull
private String clientSecret;

@NotNull
private String clientId;

@NotNull
private String accessTokenUri;

private int clientReadTimeout = 60000;
private int clientConnectTimeout = 60000;

@Bean
public OAuth2ProtectedResourceDetails oAuth2ProtectedResourceDetails() {
    ClientCredentialsResourceDetails resourceDetails = new ClientCredentialsResourceDetails();
    resourceDetails.setAccessTokenUri(accessTokenUri);
    resourceDetails.setClientId(clientId);
    resourceDetails.setClientSecret(clientSecret);
    resourceDetails.setScope(Collections.singletonList(scope));
    return resourceDetails;
}

@Bean
public OAuth2ClientContext oauth2ClientContext() {
    DefaultOAuth2ClientContext defaultOAuth2ClientContext = new DefaultOAuth2ClientContext();
    return defaultOAuth2ClientContext;
}

@Bean
public OAuth2RestTemplate oAuth2RestTemplate(OAuth2ProtectedResourceDetails oAuth2ProtectedResourceDetails, OAuth2ClientContext oauth2ClientContext) {
    OAuth2RestTemplate restTemplate = new OAuth2RestTemplate(oAuth2ProtectedResourceDetails, oauth2ClientContext);
    SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();

    restTemplate.setRequestFactory(factory);
    return restTemplate;
}
}

After updating to Spring-Boot 1.4.1 I've noticed that when autowiring the OAuth2RestTemplate another implementation of OAuth2ProtectedResourceDetails takes precedence (due to the org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ProtectedResourceDetailsConfiguration - autoconfiguration which marks a bean of AuthorizationCodeResourceDetails as primary) over our own defined bean of type ClientCredentialsResourceDetails.

I know I can fix this by not autowiring the resourceDetails and clientContext for the rest template bean and supplying the concrete implementations directly but I was just wondering whether we are configuring our rest template in a way that was not intended by the spring team?

Any thoughts on how to properly configure our rest template for the client_credentials flow?

Cheers, Ben

2

2 Answers

4
votes

I was struggling with the same issue. However, I found that if you add the annotation @EnableOAuth2Client annotation along with:

security.oauth2.client.grant-type = client_credentials

you get the proper injected ClientCredentialsResourceDetails details instance rather than the AuthorizationCodeResourceDetails. In addition, trying to exclude the OAuth2ProtectedResourceDetailsConfiguration does not work. It is a package private class. If you try to exclude it by name, you will get an error stating it is not an auto configuration class. Look at the code for OAuth2RestOperationsConfiguration class. It is what determines which resource to allocate based on inspecting properties within the security.oauth2.client prefix.

1
votes

I stuck into the same issue right now. My solution is to use a named bean for my ResourceDetails bean and use @Qualifier to inject the proper one when I'm creating the rest template (in your case in the parameters of the oAuth2RestTemplate method).

It would be nice to know the exact cause of this problem with the version upgrade between 1.4.0 and 1.4.1 though.