1
votes

Consider this microservices based application using Spring Boot 2.1.2 and Spring Cloud Greenwich.RELEASE:

  • Each microservice uses the JSESSIONID cookie to identify its own dedicated Servlet session (i.e. no global unique session shared with Spring Session and Redis).
  • External incoming requests are routed by Spring Cloud Gateway (and an Eureka registry used through Spring Cloud Netflix, but this should not be relevant).

When Spring Cloud Gateway returns a microservice response, it returns the "Set-Cookie" as-is, i.e. with the same "/" path.

When a second microservice is called by a client, the JSESSIONID from the first microservice is forwarded but ignored (since the corresponding session only exists in the first microservice). So the second microservice will return a new JSESSIONID. As a consequence the first session is lost.

In summary, each call to a different microservice will loose the previous session.

I expected some cookies path translation with Spring Cloud Gateway, but found no such feature in the docs. Not luck either with Google.

How can we fix this (a configuration parameter I could have missed, an API to write such cookies path translation, etc)?

2
There is no stickey session support. I think you can rewrite headers which is all a cookie is.spencergibb
Yes GlobalFilter seems to be of help here.Florian Beaufumé
unfortunately, jsessionid is double-used by the infrastructure and overwritten in a PCF environment. we solved the stickyness session problem you are describing with rewrite cookie name in headers as spencergibb said.mojjj

2 Answers

0
votes

Rather than changing the JSESSIONID cookies path in a GlobalFilter, I simply changed the name of the cookie in the application.yml:

# Each microservice uses its own session cookie name to prevent conflicts
server.servlet.session.cookie.name: JSESSIONID_${spring.application.name}
-1
votes

Simply reset cookie name to GATEWAY_SESSION in gateway project to avoid session conflict:

    @Autowired(required = false)
    public void setCookieName(HttpHandler httpHandler) {
        if (httpHandler == null) return;
        if (!(httpHandler instanceof HttpWebHandlerAdapter)) return;
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
        CookieWebSessionIdResolver sessionIdResolver = new CookieWebSessionIdResolver();
        sessionIdResolver.setCookieName("GATEWAY_SESSION");
        sessionManager.setSessionIdResolver(sessionIdResolver);
        ((HttpWebHandlerAdapter) httpHandler).setSessionManager(sessionManager);
    }