基于运行时凭证创建不同的Oauth2RestTemplate。

huangapple go评论116阅读模式
英文:

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 到一个映射中:

https://stackoverflow.com/questions/33996326/spring-autowire-bean-with-multiple-interface-implementations-define-implementat

但如果您知道 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:

https://stackoverflow.com/questions/33996326/spring-autowire-bean-with-multiple-interface-implementations-define-implementat

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(&quot;client_id&quot;, clientId);
    headers.add(&quot;client_secret&quot;, secret);
    return headers;
}

private void yourserviceMethod() 
{
    String theUrl = &quot;http://blah.blah.com:8080/rest/api/blah&quot;;
    try {
        HttpHeaders headers = createHttpHeaders(&quot;clintId&quot;, &quot;secret&quot;, &quot;accessToken&quot;);
        HttpEntity&lt;String&gt; entity = new HttpEntity&lt;String&gt;(&quot;parameters&quot;, headers);
        ResponseEntity&lt;String&gt; response = restTemplate.exchange(theUrl, HttpMethod.GET, entity, String.class);
        System.out.println(&quot;Result - status (&quot;+ response.getStatusCode() + &quot;) has body: &quot; + response.hasBody());
    }
    catch (Exception eek) {
        System.out.println(&quot;** Exception: &quot;+ eek.getMessage());
    }
}

huangapple
  • 本文由 发表于 2020年7月29日 04:35:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/63142371.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定