如何覆盖 Spring Cloud OAuth2 客户端自动配置?
Posted
技术标签:
【中文标题】如何覆盖 Spring Cloud OAuth2 客户端自动配置?【英文标题】:How to overwrite Spring Cloud OAuth2 client autoconfiguration? 【发布时间】: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)
我试图覆盖自动配置但失败了。有人可以给我一个提示吗?
【问题讨论】:
【参考方案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”类...以上是关于如何覆盖 Spring Cloud OAuth2 客户端自动配置?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 spring oauth2 OAuth2AccessToken 请求上设置代理或如何覆盖 OAuth2AccessTokenSupport restTemplate 变量?
如何在spring + java中添加(覆盖)oAuth2访问令牌的到期时间