【问题标题】:How to overwrite Spring Cloud OAuth2 client autoconfiguration?如何覆盖 Spring Cloud OAuth2 客户端自动配置?
【发布时间】:2015-06-24 03:43:50
【问题描述】:

我们想要设置一个提供 REST API 的微服务,以便将其配置为 OAuth2 资源服务器。此服务还应充当具有客户端凭据授权的 OAuth2 客户端。这是配置:

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>

资源服务器部分工作正常。对于客户端部分,我们想使用 Feign、Ribbon 和 Eureka:

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

基于问题https://github.com/spring-cloud/spring-cloud-security/issues/56 中的要点,我创建了一个假装请求拦截器,它从假装请求标头中的自动连接的 OAuth2RestOperations 模板设置访问令牌

@Autowired
private OAuth2RestOperations restTemplate; 

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

但这给了我调用用户服务的错误:

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

正如我所见,OAuth2ClientAutoConfiguration 始终为 Web 应用程序创建 AuthorizationCodeResourceDetails 实例,而不是仅用于非 Web 应用程序的必需 ClientCredentialsResourceDetails 实例。最后,无访问令牌提供者负责资源详细信息,并且调用失败

AccessTokenProviderChain.obtainNewAccessTokenInternal(AccessTokenProviderChain.java:146) 

我试图覆盖自动配置但失败了。有人可以给我一个提示吗?

【问题讨论】:

    标签: spring spring-security spring-boot spring-security-oauth2 spring-cloud


    【解决方案1】:

    要关闭此自动配置,您可以设置spring.oauth2.client.clientId=(空),(根据源代码),否则您必须在@EnableAutoConfiguration 中“排除”它。如果您这样做,您只需设置自己的OAuth2RestTemplate 并从您自己的配置中填写“真实”客户端 ID,例如

    @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;
      }
    
    }
    

    【讨论】:

    • 感谢您的快速回答!这是我尝试过的。排除自动配置不起作用,因为自动连接依赖项失败。我现在尝试将 clientId 设置为空,但由于某种原因,我无法自动连接 OAuth2RestOperations restTemplate,而不是我想从中获取访问令牌。有什么想法吗?
    • 我猜你也需要创建一个该类型的@Bean。我会更新答案中的代码。
    • @DaveSyer,设置 spring.oauth2.client.clientId='' (或看似等效,不设置)具有禁用 OAuth2SsoConfiguration 的额外副作用,事实证明我仍然需要。因为我需要自定义 OAuth2RestTemplate bean,所以我已经按照您在此处的建议替换了 OAuth2ClientAutoConfiguration,但是替换两者似乎只是为了自定义 OAuth2RestTemplate bean;你有其他建议吗?
    • 是的,有一个*Customizer 回调(自此线程开始后添加)。如果您希望 SSO 具有自定义的休息模板,那就是这样做的方法。
    • @DaveSyer 你能扩展对 *Customizer 回调的引用吗?您能否提供一个示例或文档链接?我似乎找不到任何提及“Customizer 回调”或任何“*Customizer”类...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-10
    • 1970-01-01
    • 2022-11-08
    • 2019-01-26
    • 2016-04-15
    • 2021-10-24
    相关资源
    最近更新 更多