在Zuul代理后面的Spring重定向url问题

时间:2016-02-17 10:24:06

标签: spring-mvc spring-boot spring-cloud netflix-eureka netflix-zuul

过去两天我一直试图找到一个奇怪的重定向问题,但没有成功。

基于spring-cloud示例项目,我已经配置了Eureka,Zuul和一个在Zuul后面运行的基本服务。

我有以下方法;

@RequestMapping(method = RequestMethod.POST, value = "/register")
public String registerDevice(Principal principal, String response) {
  // ...
  return "redirect:/account";
}

表单设置为发布到代理URL,如下所示;

POST https://localhost:8443/service/register

(Zuul在localhost:8443上运行)。

本地服务的URL(非代理)将是; http://localhost:9001/register

通过上述方法正确代理POST调用,但是发送到浏览器的重定向位置是服务的非代理URL; http://localhost:9001/account

Zuul代理肯定会发送正确的 x-forwarded - * 标头,因此我希望Spring中的视图解析器能够根据x-forwarded值构建正确的重定向。

为证明标题已正确发送,我按以下方式重新配置了该方法;

@RequestMapping(method = RequestMethod.POST, value = "/register")
public void registerDevice(Principal, String response, HttpServletResponse response) {
  // ...
  String rUrl = ServletUriComponentsBuilder.fromCurrentContextPath().path("/account").build().toUriString();
  servletResponse.sendRedirect(rUrl);
}

正确地将浏览器重定向到代理位置; https://localhost:8443/service/account

这是一个错误,还是预期的行为?我认为使用“redirect:”是为了纪念从代理传递的转发头。

2 个答案:

答案 0 :(得分:3)

如您所见,RedirectView忽略X-FORWARDED-*标题。 简而言之,您无法使用" redirect:/account"

而是实例化RedirectView并相应地配置它:

RedirectView redirect = new RedirectView("account");
redirect.setHosts(new String[]{ request.getHeader("X-FORWARDED-HOST") });

由于Spring Framework 4.3(目前为RC1)setHosts方法可用。

答案 1 :(得分:1)

如果您在后端应用程序中使用tomcat作为嵌入式服务器,则可以使用此设置(application.properties,yml等):

server.tomcat.remote_ip_header=x-forwarded-for
server.tomcat.protocol_header=x-forwarded-proto

或更通用的方式:

server.use-forward-headers=true