英文:
Creating different Oauth2RestTemplates based on credentials on Runtime
问题
我有一个如下定义的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”的错误。
请给予建议。
英文:
I have a OAuth2RestTemplate defined as below
@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;
}
Now, in the calling class, I have it annotated as below and it works fine.
@Autowired
private OAuth2RestTemplate restTemplate;
I want to make this functionality generic and create the templates based of off clientId, secret and URI. How can I achieve this? Is creating multiple @bean methods (Separate method for each credentials) and based on the caller credentials, picking the corresponding bean from a map maybe the only way to achieve this?
I tried keeping only one @bean method and passing params to restTemplate method but I keep running into No qualifying bean of type [java.lang.String] found error
Please advise
答案1
得分: 1
如果您有少量的 clientId
,例如 3 或 4 个,可以使用不同名称的多个类型为 OAuth2RestTemplate
的 bean,并在需要时使用它们。如果您想采用这种方法,请阅读以下链接以自动装配多个 bean 到一个映射中:
但如果您知道 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");
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());
}
}
英文:
If you have a few number of clientId
such as 3 or 4 it's ok to have multiple bean of type OAuth2RestTemplate
with different name and use them. if you want to go for this approach read the following link to autowire multiple bean in a map:
But if you know the number of ClientId
will dynamically change based on some parameters you can use one bean of type OAuth2RestTemplate
and change the value of clientId
header at runtime using RestTemplate Interceptor
.
Read the following link to know how to use Interceptor
:
https://howtodoinjava.com/spring-boot2/resttemplate/clienthttprequestinterceptor/
If you are determined to pass client Id at runtime based on parameter in request you can do that this way:
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());
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论