Spring проблема с перенаправлением URL-адреса, когда за Zuul proxy

Я пытаюсь разобраться с проблемой странного перенаправления в течение последних двух дней без успеха.

На основе проектов примера spring -cloud я настроил Eureka, Zuul и базовую службу, которая работает за Zuul.

У меня есть следующий метод:

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

Форма настраивается для отправки на прокси-адрес следующим образом:

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

(Zuul работает на localhost: 8443).

URL-адрес локальной службы (без прокси) будет; http://localhost:9001/register

Вызов POST проверяется корректно до указанного выше метода, однако адрес перенаправления, отправленный в браузер, является непроксированным URL-адресом службы; http://localhost:9001/account

Прокси-сервер Zuul определенно отправляет правильные заголовки x-forwarded - *, поэтому я бы ожидал, что view resolver в Spring построит правильное перенаправление на основе x-пересылаемых значений.

Чтобы доказать правильность отправки заголовков, я переконфигурировал метод следующим образом:

@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:" предназначалось для того, чтобы почтить передние заголовки, переданные из прокси.

Ответ 1

Как вы видите 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.

Ответ 2

Если вы используете tomcat как встроенный сервер в своем backend-приложении, вы можете использовать эти параметры (application.properties, yml и т.д.):

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

Или более общий способ:

server.use-forward-headers=true