10

I've been trying to get to the bottom of a strange redirection issue for the past 2 days without success.

Based on the spring-cloud example projects, I've configured Eureka, Zuul and a basic service that runs behind Zuul.

I have the following method;

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

The form is setup to post to the proxied URL as follows;

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

(Zuul is running on localhost:8443).

The URL for the local service (non-proxied) would be; http://localhost:9001/register

The POST call is proxied correctly through to the above method, however the redirect location sent to the browser is the non-proxied URL of the service; http://localhost:9001/account

The Zuul proxy is definitely sending the correct x-forwarded-* headers, so I would expect the view resolver in Spring to build the correct redirect based on the x-forwarded values.

To prove the headers are sent correctly, I reconfigured the method as follows;

@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);
}

Which correctly redirects the browser to the proxied location; https://localhost:8443/service/account

Is this a bug, or is it expected behaviour? I thought using "redirect:" was meant to honour the forward headers passed from a proxy.

JamieB
  • 1,722
  • 18
  • 21

2 Answers2

3

As you can see RedirectView ignores X-FORWARDED-* headers. Simply put, you can't use "redirect:/account".

Instead instantiate a RedirectView and configure it accordingly:

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

Since Spring Framework 4.3 (currently RC1) setHosts method is available.

ksokol
  • 8,035
  • 3
  • 43
  • 56
  • I have the same issue and don't see setHosts() in latest version of RedirectView (v4.2.5) – Damien Polegato Apr 27 '16 at 05:26
  • @damien-polegato you are right! `setHosts` method has been added in Spring Framework 4.3. I updated my answer. Thanks. – ksokol Apr 27 '16 at 07:10
  • thanks, my question with same issue here if you have any clue : http://stackoverflow.com/questions/36881835/spring-mvc-web-app-behind-zuul-redirect-issue – Damien Polegato Apr 27 '16 at 07:54
2

If you are using tomcat as embeded server in your backend app, you could use this settings (application.properties, yml, etc):

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

Or more generic way:

server.use-forward-headers=true
mawoc
  • 31
  • 4