Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring redirect url issue when behind Zuul proxy

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.

like image 683
JamieB Avatar asked Feb 17 '16 10:02

JamieB


2 Answers

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
like image 117
mawoc Avatar answered Nov 07 '22 09:11

mawoc


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.

like image 34
ksokol Avatar answered Nov 07 '22 09:11

ksokol