我有一个充当网关的spring boot微服务,需要从请求获取授权标头,将其附加到新请求,然后将请求传递给另一个微服务。我目前正在执行以下操作,并且可以正常工作,但是想知道是否有更好的方法可以执行此操作。
@GetMapping
public List<Task> getTasks(HttpServletRequest request, HttpServletResponse httpresponse) {
String bearerToken = request.getHeader("Authorization");
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.set("Authorization", bearerToken);
HttpEntity<String> httpEntity = new HttpEntity <String> (httpHeaders);
String getTasksURL = "http://localhost:8082/tasks";
ResponseEntity<List<Task>> response = restTemplate.exchange(
getTasksURL,
HttpMethod.GET,
httpEntity,
new ParameterizedTypeReference<List<Task>>(){});
List<Task> taskslist = response.getBody();
return taskslist;
}
如果有使用jwt的代码示例,请提供链接。大多数代码示例仅显示单个微服务中jwt的配置,但是没有看到最终调用另一个微服务并来回传递令牌的项目
答案 0 :(得分:1)
我认为您的操作方式没有任何问题。但是,如果您实现的网关只是传递请求(可能具有一定的速率限制或安全性,但实际上不是业务逻辑),则建议您检出http://spring.io/projects/spring-cloud-netflix-Zuul代理部分。您仅需几个类就可以拥有一个完全正常运行的API网关,包括配置在内的总共<200行代码。很好!
答案 1 :(得分:1)
将处理授权的代码封装在单独的拦截器中可能更好。这样,您的代码将变得更加简单清晰。
这样的拦截器可能看起来像:
class RestTemplateHeaderModifierInterceptor implements ClientHttpRequestInterceptor {
@Override
public ClientHttpResponse intercept(
HttpRequest request,
byte[] body,
ClientHttpRequestExecution execution) throws IOException {
// Set your new Header here...
// ...
ClientHttpResponse response = execution.execute(request, body);
return response;
}}
现在,您必须在其创建过程中将此拦截器添加到restTemplate中
@Bean
public RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate(clientHttpRequestFactory());
restTemplate.setInterceptors(Collections.singletonList(new RestTemplateHeaderModifierInterceptor()));
return restTemplate;
}
答案 2 :(得分:0)
最好使用zuul代理作为网关。但是请记住,默认情况下它不会将您的授权标头转发给外部服务。而且,如果您要这样做,则只需通过一个线路配置即可完成。你可以看 How to get username from JWT token while requesting for another service after authentication?