0

I'm a bit new to microservices and Spring. I have Spring Cloud microservices (ports: 8xxx-8xxx) with a Zuul gateway running on port 9000. There's a method inside a controller on a UI service which should do a login and then return to a index.html page:

@RequestMapping(value="/do-login", method = RequestMethod.POST)
    public RedirectView doLogin (@ModelAttribute("authEntity") final AuthEntity authEntity, final Model model) {
        model.addAttribute(VERSION, applicationVersion);
        model.addAttribute("authEntity", new AuthEntity());
        authenticatedStatus = true;
        model.addAttribute(AUTHENTICATED, authenticatedStatus);

        return new RedirectView("index");
    }

The problem is that when above method completes it returns an url of the microservice itself localhost:8888/index but not localhost:9000/services/ui/.

If I use a simpler method:

@RequestMapping(value="/do-login", method = RequestMethod.POST)
public String doLogin (@ModelAttribute("authEntity") final AuthEntity authEntity, final Model model) {
    model.addAttribute(VERSION, applicationVersion);
    model.addAttribute("authEntity", new AuthEntity());
    authenticatedStatus = true;
    model.addAttribute(AUTHENTICATED, authenticatedStatus);

    return "index";
}

This returns correctly an url of gateway localhost:9000/services/ui/do-login but with a /do-login which I do not need.

Maybe I can get rid of /do-login/ part of url? Or maybe there is a solution for the incorrect redirect?

Thanks in advance!

Deniss M.
  • 3,617
  • 17
  • 52
  • 100

2 Answers2

0

If you use relative path like in return "index"; the result of the POST request sent to http://localhost:9000/services/ui/do-login will include URLs to http://localhost:9000/... unless coded otherwise in the jsp / freemarker / thymeleaf file.

If you want to get rid of the do-login, you would need to implement what's called a Redirect After Post (or redirect after form submit) approach so that a page refresh doesn't resubmit the form. If you take this approach, which seem what you were doing when using: return new RedirectView("index");, I can think of a couple ways of fixing the URL and set it to the proxy host.

1) http://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/view/RedirectView.html, there are a couple of constructors that takes a host parameter, you would need to inject the proxy host in the controller class and most-likely in every controller class that implements Redirect After Post.

2) http://tuckey.org/urlrewrite/, include UrlRewriteFilter and configure rules to rewrite from webapp host to proxy host when webapp http status code response is 302. With this approach it would only be once rule and no need to inject proxy host to controller classes or change the return new RedirectView("index");`

3) Maybe this rewriting is implemented in Zuul and you don't need include and configure UrlRewriteFilter as suggested in 2).

As a side note, I have configured Nginx's proxy_pass to a Java webapps (where I implemented Redirect After Post) in the past and I don't recall having this issue. Will have to take a look at both UrlRewriteFilter and Nginx config files to expand on this.

ootero
  • 3,235
  • 2
  • 16
  • 22
0

I found that this (thanks to answer in here: Spring redirect url issue when behind Zuul proxy) seems to work as required (but is considered a 'workaround'):

@RequestMapping(value="/do-login", method = RequestMethod.POST)
    public void doLogin (@ModelAttribute("authEntity") final AuthEntity authEntity,
                         final Model model,
                         HttpServletResponse servletResponse) throws IOException {
        ...

        String rUrl = ServletUriComponentsBuilder.fromCurrentContextPath().path("/").build().toUriString();
        servletResponse.sendRedirect(rUrl);
    }
Community
  • 1
  • 1
Deniss M.
  • 3,617
  • 17
  • 52
  • 100