【问题标题】:Spring boot - corrupt authorization header value after RestTemplate.exchange()Spring boot - RestTemplate.exchange() 后损坏的授权标头值
【发布时间】:2021-11-06 06:31:00
【问题描述】:

我遇到了一个奇怪的问题,我在微服务环境中使用令牌,我需要使用已经生成的令牌调用另一个服务。

调用客户端类上的其他服务...有方法。

return restTemplate.exchange(URL_REST_METHOD,
                HttpMethod.GET,
                httpEntity, //HEADER OK
                SubscriptionDto.class,
                subscriptionId);

为了简单起见,我获取了上一个请求,获取令牌并添加到当前请求中。

public class HeaderLoginInterceptor implements ClientHttpRequestInterceptor {

    @Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
        HttpServletRequest previousRequest = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        if(previousRequest.getHeader(AUTHORIZATION) != null){
            request.getHeaders().add(AUTHORIZATION, previousRequest.getHeader(AUTHORIZATION));
        }
        return execution.execute(request, body);
    }

}

我将此拦截器附加到 Bean RestTemplate

@Bean
public RestTemplate restTemplate() {
    RestTemplate restTemplate = new RestTemplate();

    List<ClientHttpRequestInterceptor> interceptors
            = restTemplate.getInterceptors();
    if (CollectionUtils.isEmpty(interceptors)) {
        interceptors = new ArrayList<>();
    }
    interceptors.add(new HeaderLoginInterceptor());
    restTemplate.setInterceptors(interceptors);
    return restTemplate;
}

奇怪的是,执行后,我在 Authorization 标头上看到了一个缺陷:

正确的一个:


承载 eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJhdWQiOiJBZGlkYXMgQ2hhbGxlbmdlIiwic3...


之后很奇怪:

承载 eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJhdWQiOiJBZGlkYXMgQ2hhbGxlbmdlIiwic3...


我尝试在调用交换方法之前直接添加令牌,结果相同。

HttpServletRequest previousRequest = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
HttpHeaders headers = new HttpHeaders();
headers.addAll((MultiValueMap<String, String>) previousRequest.getHeaderNames());
HttpEntity<?> httpEntity = new HttpEntity<>(new HttpHeaders());

在这两种情况下,调用方法 restTemplate.exchange(...) 后都会损坏。

有什么想法吗?

非常感谢

【问题讨论】:

    标签: spring-boot


    【解决方案1】:

    经过大量研究,问题与RestTemplate的字符集有关。

    如果我在@Bean配置上添加这一行,问题就解决了:

    @Bean
    public RestTemplate restTemplate() {
        RestTemplate restTemplate = new RestTemplate();
        /*** THE SAVERY LINE ***/
        restTemplate.getMessageConverters().add(0, new StringHttpMessageConverter(Charset.forName("UTF-8")));
        /*** ***/
        List<ClientHttpRequestInterceptor> interceptors
                = restTemplate.getInterceptors();
        if (CollectionUtils.isEmpty(interceptors)) {
            interceptors = new ArrayList<>();
        }
        interceptors.add(new HeaderLoginInterceptor());
        restTemplate.setInterceptors(interceptors);
        return restTemplate;
    }
    

    之后,就可以正常工作了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-01-28
      • 2017-03-22
      • 2017-06-21
      • 2019-03-09
      • 1970-01-01
      • 2021-06-20
      • 2019-07-19
      • 1970-01-01
      相关资源
      最近更新 更多