基于运行时的凭据创建不同的 Oauth2RestTemplates
Posted
技术标签:
【中文标题】基于运行时的凭据创建不同的 Oauth2RestTemplates【英文标题】:Creating different Oauth2RestTemplates based on credentials on Runtime 【发布时间】:2020-11-18 09:08:20 【问题描述】:我有一个 OAuth2RestTemplate 定义如下
@Configuration
@EnableOAuth2Client
public class TestOauth
@Bean
public OAuth2RestTemplate restTemplate()
OAuth2RestTemplate restTemplate= new OAuth2RestTemplate(buildResourceDetails());
restTemplate.setRequestFactory(new BufferingClientHttpRequestFactory(new
HttpComponentsClientHttpRequestFactory()));
return restTemplate;
@Bean
public ClientCredentialsResourceDetails buildResourceDetails()
ClientCredentialsResourceDetails resourceDetails = new ClientCredentialsResourceDetails();
resourceDetails.setClientId("TestId");
resourceDetails.setClientSecret("TestSecret");
resourceDetails.setAccessTokenUri("TestURI");
return resourceDetails;
现在,在调用类中,我将其注释如下,它工作正常。
@Autowired
private OAuth2RestTemplate restTemplate;
我想使这个功能通用,并基于非 clientId、secret 和 URI 创建模板。我怎样才能做到这一点?是否创建多个 @bean 方法(每个凭据的单独方法)并基于调用者凭据,从映射中选择相应的 bean 可能是实现此目的的唯一方法?
我尝试只保留一个 @bean 方法并将参数传递给 restTemplate 方法,但我一直遇到 没有找到 [java.lang.String] 类型的合格 bean 错误
请指教
【问题讨论】:
你有多少个clientId? 现在大约 3 个,但我们正在考虑在不久的将来增加到 20 个。 【参考方案1】:如果您有几个clientId
,例如3 或4,则可以拥有多个OAuth2RestTemplate
类型的bean 并使用不同的名称并使用它们。如果您想采用这种方法,请阅读以下链接以在地图中自动装配多个 bean:
Spring Autowire Bean with multiple Interface Implementations, define Implementation in method
但如果您知道ClientId
的数量会根据某些参数动态变化,您可以使用OAuth2RestTemplate
类型的一个bean,并在运行时使用RestTemplate Interceptor
更改clientId
标头的值。
阅读以下链接了解如何使用Interceptor
:
https://howtodoinjava.com/spring-boot2/resttemplate/clienthttprequestinterceptor/
如果您确定在运行时根据请求中的参数传递客户端 ID,您可以这样做:
private HttpHeaders createHttpHeaders(String clientId, String secret)
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.add("client_id", clientId);
headers.add("client_secret", secret);
return headers;
private void yourserviceMethod()
String theUrl = "http://blah.blah.com:8080/rest/api/blah";
try
HttpHeaders headers = createHttpHeaders("clintId", "secret", "accessToken");
HttpEntity<String> entity = new HttpEntity<String>("parameters", headers);
ResponseEntity<String> response = restTemplate.exchange(theUrl, HttpMethod.GET, entity, String.class);
System.out.println("Result - status ("+ response.getStatusCode() + ") has body: " + response.hasBody());
catch (Exception eek)
System.out.println("** Exception: "+ eek.getMessage());
【讨论】:
Super.. 类似于肥皂处理程序对吧?让我看看谢谢。 实际上拦截器不起作用,因为凭据是根据某些条件选择的,而不是存储在属性文件中。 您的意思是您想决定将哪个clientId
设置为您的服务中的标头?如果这是您的要求,您可以在服务中调用 Restemplate 方法时将 clientId
设置为标头
如何在运行时将 clientid 传递给拦截器?
我无法根据拦截器中请求的详细信息来区分选择哪个clientid。以上是关于基于运行时的凭据创建不同的 Oauth2RestTemplates的主要内容,如果未能解决你的问题,请参考以下文章