【问题标题】:RestTemplate with Bearer Authorization具有承载授权的 RestTemplate
【发布时间】:2020-05-12 16:54:57
【问题描述】:

是否可以使用 RestTemplateBuilder 创建仅带有不记名标头和令牌的 RestTemplate 实例?

我知道我可以使用 RestTemplate 交换并在 HttpEntity 中设置我的标头,但是否可以执行以下操作:

public RestTemplate getRestTemplate(){
    RestTemplateBuilder builder = new RestTemplateBuilder();
    return builder.build().exchange().setBearerAuth("token here"); //this is not possible
}

希望你明白我想做什么。

【问题讨论】:

    标签: java spring spring-boot resttemplate


    【解决方案1】:

    正如lilalinux 在评论中指出的那样-授权是标头的名称,而承载+令牌本身就是值。

    @Bean(name = "myRestTemplate")
    public RestTemplate collectCentRestTemplate(RestTemplateBuilder builder) {
        return builder.rootUri("some uri")
                .additionalInterceptors((ClientHttpRequestInterceptor) (request, body, execution) -> {
                    request.getHeaders().add("Authorization", "Bearer " + token);
                    return execution.execute(request, body);
                }).build();
    }
    

    谢谢:)

    【讨论】:

    • 另外,和linalinux的评论一样,“Bearer”后面应该有一个空格。即“承载”+令牌
    【解决方案2】:

    这对我有用,

    restTemplate.getInterceptors().add((outReq, bytes, clientHttpReqExec) -> {
                outReq.getHeaders().set(
                        HttpHeaders.AUTHORIZATION, "Bearer " + token
                      );
                      return clientHttpReqExec.execute(outReq, bytes);
                    });
    restTemplate.getForObject(...
    restTemplate.postForObject(....
    

    【讨论】:

      【解决方案3】:

      您可以像这样使用拦截器将令牌注入到请求标头中

          @Bean(name = "myRestTemplate")
          public RestTemplate someRestTemplate(RestTemplateBuilder builder) {
              return builder.rootUri("some uri")
                      .additionalInterceptors((ClientHttpRequestInterceptor) (request, body, execution) -> {
                          request.getHeaders().add("Bearer", "token");
                          return execution.execute(request, body);
                      }).build();
          }
      

      在您的应用中,您可以像这样简单地使用

          @Autowired
          @Qualifier("myRestTemplate")
          private RestTemplate restTemplate;
      

      请记住,您仍然可以像往常一样使用 restTemplate 对象,设置标头等,但是 Bearer 标头将始终被 "token" 覆盖,因为拦截器会在之前应用提出请求

      【讨论】:

      • 当我调用这个 RestTemplate 时,我还能像往常一样添加更多标题和正文吗?
      • @svrdoljak,是的,但是 Bearer 标头将始终被覆盖
      • header大概应该是:request.getHeaders().add("Authorization", "Bearer" + token),即在token之前的value部分中的Bearer,名称为"Authorization"标题。
      【解决方案4】:
          HttpHeaders headers = new HttpHeaders();
          headers.add("Authorization" , "Bearer token");
          HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<(headers);
      
          ResponseEntity<Object> response = null;
      
          UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl("url");
          try {
              response = restTemplate.exchange(builder.toUriString(),
                      HttpMethod.GET,
                      entity, Object.class);
          } catch (Exception e) {
              e.printStackTrace();
          }
      

      你可以试试这个。

      【讨论】:

        【解决方案5】:

        您可以使用OAuth2RestTemplate,它完全适合您的目的。

        【讨论】:

          【解决方案6】:

          不,有人建议和declined为 RestTemplateBuilder 中的 Headers 提供方便的方法

          我认为目前最简单的方法是这样做:

          RequestEntity<Void> request = RequestEntity.post(url)
              .accept(MediaType.APPLICATION_JSON).header("foo", "bar").build();
          restTemplate.exchange(request, String.class);
          

          我倾向于同意@wilkinsona 的观点,即添加额外的说服方法可能不如当前的 basicAuthorization 方法有用。那是很常见的,当它被添加时,自己编写代码非常痛苦(自从 Spring 4.3.1 添加了 BasicAuthorizationInterceptor 类后,现在变得更容易了)。

          我们需要在任何新的便利方法的便利性与有太多方法来做同样事情的复杂性之间取得平衡。由于为任何需要此行为的应用程序插入 RestTemplateCustomizer 相对容易,我认为我们不应该添加这些。

          【讨论】:

            猜你喜欢
            • 2019-09-03
            • 2016-02-23
            • 1970-01-01
            • 1970-01-01
            • 2017-12-03
            • 2013-07-10
            • 2021-06-18
            • 1970-01-01
            • 2018-10-11
            相关资源
            最近更新 更多