spring-bootspring-cloudspring-security-oauth2pcfdev

UserInfoRestTemplateFactory setup fails with ResourceServerConfigurerAdapter and two spring-cloud-services-starters


I've slightly updated an Spring Cloud Services example to illustrate a problem that I'm having: https://github.com/spring-cloud-services-samples/greeting/compare/master...timtebeek:master

After the above changes I'm using:

I've also added a minimal ResourceServerConfigurerAdapter

@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
  @Override
  public void configure(final HttpSecurity http) throws Exception {
    http.authorizeRequests().anyRequest().authenticated();
  }

  @Override
  public void configure(final ResourceServerSecurityConfigurer resources) {
    resources.resourceId("greeter");
  }
}

And the bare minimum configuration setting:

security: oauth2: resource: jwt: key-uri: https://example.com/oauth/token_key

With these changes my application fails to deploy in PCF-DEV; I've not tried PCF proper, but expect the results to be similar. Here's the error message I get:

Method userInfoRestTemplateFactory in org.springframework.boot.autoconfigure.security.oauth2.resource.ResourceServerTokenServicesConfiguration required a single bean, but 2 were found: - eurekaOAuth2ResourceDetails: defined by method 'eurekaOAuth2ResourceDetails' in class path resource [io/pivotal/spring/cloud/service/eureka/EurekaOAuth2AutoConfiguration.class] - configClientOAuth2ResourceDetails: defined by method 'configClientOAuth2ResourceDetails' in io.pivotal.spring.cloud.service.config.ConfigClientOAuth2BootstrapConfiguration Action: Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed

So it's trying to use what should be completely separate OAuth2ProtectedResourceDetails from spring-cloud-services-starters to setup my application security; Where I would want it to use the external JWT key only.

Can anyone help me with how I can have my PCF deployed application using both config and discovery services also use an external JWT token for authentication setup?


Solution

  • I ran into the same thing. I saw this thread a few months ago. I also upgraded to spring boot 1.5.4 and cloud Dalston.SR4 and that got me over the hump. Thanks.

    I was shown that http://start.spring.io was using spring boot 1.5.9. It runs on PivotalWS, so I knew there was a solution.

    Try this change:

    security:
      oauth2:
        client:
          client-id: someclient
          client-secret: someclientpass
        resource:
          jwt:
            key-uri: https://example.com/oauth/token_key
    

    The client-id and client-secret are dummy values in my case. I assume since you are also using JWT token, that your resource doesn't need to validate the token with your JWT token provider, only the signature (key-uri).

    So by adding the client-id and client-secret, I'm guessing (totally guessing) that it creates the required OAuth2ProtectedResourceDetails with a better (closer) scope.

    The fact that it was looking for "userInfoRestTemplateFactory" when we don't need to lookup user info is what pointed me in this direction.

    My services are successfully deploying on PivotalWS (run.pivotal.io) with this change, using spring boot 1.5.9 and Dalston.SR4 with io.pivotal.spring.cloud:spring-cloud-services-dependencies:1.5.0.RELEASE