Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

cookies with <path>/</path> and JSESSIONID

I am experimenting with setting the cookie path in my application's web.xml (as suggested here) to:

<session-config>
    <cookie-config>
        <path>/</path>
    </cookie-config>
</session-config>

So I deploy two identical web applications to localhost:8080/application-a and localhost:8080/application-b respectively.

Each application is a single servlet:

public class ControllerServlet extends HttpServlet{
  @Override
  public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
      HttpSession session = req.getSession(false);

      if (session == null) {
          session = req.getSession(true);
          System.out.printf("No session was present - new one created with JSESSIONID=[%s]\n", session.getId());
      } else {
          System.out.printf("JSESSIONID cookie was present and HttpSession objects exists with JSESSIONID=[%s]\n", session.getId());
      }
  }
}

I deploy the apps to a Tomcat 8.5 container (tried with Tomcat 9 as well the behavior is the same). When I visit with my browser the application-a, here's what I see:

enter image description here

… and on the Tomcat logs I read:

No session was present - new one created with JSESSIONID=[A227B147A4027B7C37D31A4A62104DA9]

So far so good. When I then visit application-b here's what I see:

enter image description here

… and the Tomcat logs show:

No session was present - new one created with JSESSIONID=[5DC8554459233F726628875E22D57AD5]

This is also very well as explained here and also in this answer and I quote:

SRV.7.3 Session Scope

HttpSession objects must be scoped at the application (or servlet context) level. The underlying mechanism, such as the cookie used to establish the session, can be the same for different contexts, but the object referenced, including the attributes in that object, must never be shared between contexts by the container.

So even though on the request the JSESSIONID cookie was present, my application (the one deployed in application-b) was unable to find an HttpSession object in its own servlet context scope and so a new session object was created and a new value was assigned to the JSESSIONID cookie.

However, when I now go back to my application-a I find out that because of the / value configured for the cookie path, it is now trying to use the JSESSIONID value set by application-b and of course its servlet doesn't find such a session object in its own context (application-a) and so a new value for the JSESSIONID cookie is created which will in turn invalidate the session of the application-b application and so on and so forth ad infinitum as I switch back and forth between the two applications.

So my questions are:

1 given the above behavior it would seem impossible for two applications to use the same JSESSIONID cookie value as the key to their respective HttpSession objects. So in fact not only are the HttpSession objects always different and scoped at the application (servlet context) level but also, in practice, the JSESSIONID values have to be different. Is that correct?

2 If so, then why does the servlet specification use the wording:

The underlying mechanism, such as the cookie used to establish the session, can be the same for different contexts [...]

The only way I can imagine the above could be accomplished would be to have a way to hardcodedly provide the JSESSIONID value to use when a new session object is created? But I don't see an API for that.

3 Is there a way I can have some other cookies be shared among applications using the / path in the <session-config> XML element but not have the / path apply to the JSESSIONID cookie? In other words does the <session-config> apply to all cookies of an application or only the cookie used for session tracking? (JSESSIONID) ?

like image 537
Marcus Junius Brutus Avatar asked Nov 22 '16 23:11

Marcus Junius Brutus


People also ask

What is the Jsessionid cookie?

JSESSIONID is a cookie generated by Servlet containers and used for session management in J2EE web applications for HTTP protocol. If a Web server is using a cookie for session management, it creates and sends JSESSIONID cookie to the client and then the client sends it back to the server in subsequent HTTP requests.

How do I set cookies to all path?

In your Java server, you should call cookie. setPath("/") before adding it to response. Such cookie will match all request URIs.

How do I store Jsessionid?

To Start off the JSESSIONID is stored in a cookie. If cookies are turned off, you have to get into url rewritting to store the jsessionid in the url. There is nothing else about the session in cookies.


1 Answers

Upon further experimentation and taking a cue from this answer it would appear that for the same JSESSIONID to be used for all web applications it is necessary to set the following attribute in context.xml:

<Context ... sessionCookiePath="/">

Either the Tomcat-wide context.xml or the WAR-specific context.xml will do. The <cookie-config><path> value configured in the WAR's web.xml is apparently ignored.

Regarding point 3 of my question I 've found that the way to set paths for other cookies is to programmatically create many of them, one for each path, and add them in the response object with the addCookie method. The configurations in web.xml or context.xml are appicable to other cookies beyond the session cookie.

like image 194
Marcus Junius Brutus Avatar answered Sep 20 '22 06:09

Marcus Junius Brutus