Marcus Junius Brutus Marcus Junius Brutus - 8 days ago 4
Java Question

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) ?

Answer

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. So at this point even though I've addressed the question it is still not clear to me what the <cooke-config><path> element is supposed to serve for.

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.

Comments