使用 spring rest 模板在服务上传播 HTTP 标头 (JWT 令牌)

2022-09-03 18:36:16

我有一个微服务架构,它们都由Spring安全性和JWT令牌保护。

因此,当我调用我的第一个微服务时,我想获取 JWT 令牌,并使用这些凭据向另一个服务发送请求。

如何检索令牌并再次发送到其他服务?


答案 1

基本上,您的令牌应位于请求的标头中,例如:授权:持有者。要获取它,您可以通过在控制器中@RequestHeader()来检索任何标头值:

@GetMapping("/someMapping")
public String someMethod(@RequestHeader("Authorization") String token) {

}

现在,您可以将令牌放在以下请求的标头中:

HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", token);

HttpEntity<RestRequest> entityReq = new HttpEntity<RestRequest>(request, headers);

现在,您可以将 HttpEntity 传递到 rest 模板:

template.exchange("RestSvcUrl", HttpMethod.POST, entityReq, SomeResponse.class);

希望我能帮忙


答案 2

我已经完成了任务,创建了一个自定义过滤器

public class RequestFilter implements Filter{



    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        String token = httpServletRequest.getHeader(RequestContext.REQUEST_HEADER_NAME);

        if (token == null || "".equals(token)) {
            throw new IllegalArgumentException("Can't retrieve JWT Token");
        }

        RequestContext.getContext().setToken(token);
        chain.doFilter(request, response);

    }

    @Override
    public void destroy() { }

    @Override
    public void init(FilterConfig arg0) throws ServletException {}


}

然后,在我的配置中设置

    @Bean
public FilterRegistrationBean getPeticionFilter() {

    FilterRegistrationBean registration = new FilterRegistrationBean();
    registration.setFilter(new RequestFilter());
    registration.addUrlPatterns("/*");
    registration.setName("requestFilter");

    return registration;
}

考虑到这一点,我创建了另一个带有ThreadLocal变量的类,以将JWT令牌从控制器传递到Rest Templace拦截器。

public class RequestContext {

public static final String REQUEST_HEADER_NAME = "Authorization";

private static final ThreadLocal<RequestContext> CONTEXT = new ThreadLocal<>();

private String token;

public static RequestContext getContext() {
    RequestContext result = CONTEXT.get();

    if (result == null) {
        result = new RequestContext();
        CONTEXT.set(result);
    }

    return result;
}

public String getToken() {
    return token;
}

public void setToken(String token) {
    this.token = token;
}

}

public class RestTemplateInterceptor implements ClientHttpRequestInterceptor{

@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {

    String token = RequestContext.getContext().getToken();

    request.getHeaders().add(RequestContext.REQUEST_HEADER_NAME, token);

    return execution.execute(request, body);

}

}

将拦截器添加到配置

  @PostConstruct
public void addInterceptors() {
    List<ClientHttpRequestInterceptor> interceptors = restTemplate.getInterceptors();
    interceptors.add(new RestTemplateInterceptor());
    restTemplate.setInterceptors(interceptors);
}