Java 在运行时基于凭据创建不同的Oauth2RestTemplates

Java 在运行时基于凭据创建不同的Oauth2RestTemplates,java,spring,rest,spring-security,oauth-2.0,Java,Spring,Rest,Spring Security,Oauth 2.0,我有一个OAuth2RestTemplate,定义如下 @Configuration @EnableOAuth2Client public class TestOauth{ @Bean public OAuth2RestTemplate restTemplate(){ OAuth2RestTemplate restTemplate= new OAuth2RestTemplate(buildResourceDetails()); restTemplate.setRequestFa

我有一个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;
我想使这个功能通用化,并创建基于off-clientId、secret和URI的模板。我怎样才能做到这一点?创建多个@bean方法(每个凭据的单独方法)并基于调用方凭据,从映射中选择相应的bean可能是实现这一点的唯一方法吗

我试图只保留一个@bean方法,并将参数传递给restTemplate方法,但我一直没有遇到[java.lang.String]类型的合格bean发现错误


请建议

如果您有一些
clientId
,例如3或4,可以使用多个具有不同名称的
OAuth2RestTemplate
类型的bean并使用它们。如果您想采用这种方法,请阅读以下链接,以自动连接地图中的多个bean:

但是如果您知道
ClientId
的数量将根据一些参数动态变化,那么您可以使用类型为
OAuth2RestTemplate
的bean,并在运行时使用
RestTemplate拦截器
更改
ClientId
头的值

阅读以下链接了解如何使用
拦截器

如果您决定根据请求中的参数在运行时传递客户端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());
    }
}
private HttpHeaders createHttpHeaders(字符串clientId,字符串secret)
{
HttpHeaders=新的HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
添加(“客户端id”,clientId);
添加(“客户机密”,机密);
返回标题;
}
私有void yourserviceMethod()
{
字符串URL=”http://blah.blah.com:8080/rest/api/blah";
试一试{
HttpHeaders headers=createHttpHeaders(“clintId”、“secret”、“accessToken”);
HttpEntity=新的HttpEntity(“参数”,标题);
ResponseEntity response=restemplate.exchange(URL、HttpMethod.GET、entity、String.class);
System.out.println(“结果-状态(“+response.getStatusCode()+”)有主体:“+response.hasBody()”);
}
捕获(异常eek){
System.out.println(“**异常:+eek.getMessage());
}
}

您有多少个客户ID?现在大约3个,但我们正在考虑在不久的将来增加到20个。超级。。类似于soap处理程序,对吗?让我检查一下,谢谢。实际上拦截器不会工作,因为凭据是根据特定条件选择的,并且不会存储在属性文件中。您的意思是要决定在您的服务中将哪个
clientId
设置为标头?如果这是您的要求,那么在调用服务中的重新模板方法时,您可以将
clientId
设置为标头。如何在运行时将clientId传递给拦截器?我无法根据拦截器中请求的详细信息来区分要选择哪个clientId。