How to overwrite Spring Cloud OAuth2 client autoconfiguration?

10,250

To switch off this piece of autoconfiguration you can set spring.oauth2.client.clientId= (empty), (per the source code), otherwise you have to "exclude" it in the @EnableAutoConfiguration. If you do that you can just set up your own OAuth2RestTemplate and fill in the "real" client ID from your own configuration, e.g.

@Configuration
@EnableOAuth2Client
public class MyConfiguration {

  @Value("myClientId")
  String myClientId;

  @Bean
  @ConfigurationProperties("spring.oauth2.client")
  @Primary
  public ClientCredentialsResourceDetails oauth2RemoteResource() {
    ClientCredentialsResourceDetails details = new ClientCredentialsResourceDetails();
    details.setClientId(myClientId);
    return details;
  }

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

  @Bean
  @Primary
  public OAuth2RestTemplate oauth2RestTemplate(
      OAuth2ClientContext oauth2ClientContext,
      OAuth2ProtectedResourceDetails details) {
    OAuth2RestTemplate template = new OAuth2RestTemplate(details,
      oauth2ClientContext);
    return template;
  }

}
Share:
10,250
Daniel Sass
Author by

Daniel Sass

developer, software architect, addicted quadcopter pilot

Updated on July 25, 2022

Comments

  • Daniel Sass
    Daniel Sass over 1 year

    We want to setup a microservice which provides a REST API so it is configured as a OAuth2 resource server. This service should also act as a OAuth2 client with the client credential grant. Here is the configuration:

    spring.oauth2.client.id=clientCredentialsResource
    spring.oauth2.client.accessTokenUri=http://localhost:9003/oauth/token
    spring.oauth2.client.userAuthorizationUri=http://localhost:9003/oauth/authorize
    spring.oauth2.client.grantType=client_credentials
    spring.oauth2.client.clientId=<service-id>
    spring.oauth2.client.clientSecret=<service-pw>
    

    The resource server part works fine. For the client part we want to use Feign, Ribbon and Eureka:

    @FeignClient("user")
    public interface UserClient
    {
      @RequestMapping( method = RequestMethod.GET, value = "/user/{uid}")
      Map<String, String> getUser(@PathVariable("uid") String uid);
    }
    

    Based on the gist in issue https://github.com/spring-cloud/spring-cloud-security/issues/56 I created a feign request intercepter which sets the access token from the autowired OAuth2RestOperations template in the feign request header

    @Autowired
    private OAuth2RestOperations restTemplate; 
    
    template.header(headerName, String.format("%s %s", tokenTypeName, restTemplate.getAccessToken().toString()));
    

    But this gives me the error on calling the user service:

    error="access_denied", error_description="Unable to obtain a new access token for resource 'clientCredentialsResource'. The provider manager is not configured to support it.
    

    As I can see the OAuth2ClientAutoConfiguration creates always an instance of AuthorizationCodeResourceDetails for an web application but not the required ClientCredentialsResourceDetails which is only used for non-web applications. In the end the no access token privider is responsible for the resource details and the call failed in

    AccessTokenProviderChain.obtainNewAccessTokenInternal(AccessTokenProviderChain.java:146) 
    

    I tried to overwrite the auto configuration but failed. Can somebody please give me a hint how to do it?