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