具有<path> / </ path>和JSESSIONID的cookie

Mar*_*tus 5 java cookies session tomcat

我在我的应用程序的web.xml设置Cookie路径(如建议尝试在这里)到:

<session-config>
    <cookie-config>
        <path>/</path>
    </cookie-config>
</session-config>
Run Code Online (Sandbox Code Playgroud)

因此,我分别向localhost:8080/application-a和部署了两个相同的Web应用程序localhost:8080/application-b

每个应用程序都是一个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());
      }
  }
}
Run Code Online (Sandbox Code Playgroud)

我将应用程序部署到Tomcat 8.5容器(与Tomcat 9进行了尝试,并且行为相同)。当我使用浏览器访问时application-a,会看到以下内容:

在此处输入图片说明

……在Tomcat日志上,我读到:

No session was present - new one created with JSESSIONID=[A227B147A4027B7C37D31A4A62104DA9]
Run Code Online (Sandbox Code Playgroud)

到目前为止,一切都很好。然后,当我访问application-b这里时,我会看到:

在此处输入图片说明

…,Tomcat日志显示:

No session was present - new one created with JSESSIONID=[5DC8554459233F726628875E22D57AD5]
Run Code Online (Sandbox Code Playgroud)

正如此处以及此答案中所解释的,这也很好,我引用:

SRV.7.3会议范围

HttpSession对象的作用域必须在应用程序(或Servlet上下文)级别。底层机制(例如用于建立会话的cookie)对于不同的上下文可以是相同的,但是容器绝不能在上下文之间共享引用的对象(包括该对象中的属性)。

因此,即使JSESSIONID存在请求cookie,我的应用程序(部署在中的应用程序application-b)也无法在其自己的servlet上下文范围内找到HttpSession对象,因此创建了一个新的会话对象,并将新值分配给了JSESSIONIDcookie。

但是,当我现在回到自己的位置时,application-a我发现由于/为cookie路径配置了值,它现在正尝试使用JSESSIONID设置的值application-b,当然,它的servlet在其自身的上下文中找不到这样的会话对象。 (application-a),因此会为JSESSIONIDcookie创建一个新值,这将使application-b应用程序的会话无效,依此类推,无限循环等等,因为我在两个应用程序之间来回切换。

所以我的问题是:

1给出的上述行为它似乎不可能两个应用程序使用相同的JSESSIONIDcookie值为重点,以各自的HttpSession对象。因此,实际上,不仅HttpSession对象总是不同并且在应用程序(servlet上下文)级别范围内,而且在实践中,JSESSIONID值也必须不同。那是对的吗?

2如果是这样,那么servlet规范为什么使用这样的措辞:

基础机制,例如用于建立会话的cookie,对于不同的上下文可以相同[...]

我可以想象实现上述目标的唯一方法是,有一种方法可以硬编码提供JSESSIONID创建新会话对象时要使用的值?但是我没有看到一个API。

3是否有一种方法可以使用/<session-config> XML元素中的路径在应用程序之间共享其他cookie,但没有将/路径应用于JSESSIONIDcookie?换句话说,<session-config>适用于应用程序的所有cookie还是仅适用于会话跟踪的cookie?(JSESSIONID)?

Mar*_*tus 5

根据进一步的实验并从这个答案中得到提示,对于要用于所有 Web 应用程序的相同 JSESSIONID,似乎有必要在 context.xml 中设置以下属性:

<Context ... sessionCookiePath="/">
Run Code Online (Sandbox Code Playgroud)

无论是Tomcat的范围context.xml中在WAR特定的context.xml会做。<cookie-config><path>WAR 的 web.xml 中配置的值显然被忽略了。

关于我的问题的第3点,我发现为其他 cookie 设置路径的方法是以编程方式创建许多 cookie,每个路径一个,并使用addCookie方法将它们添加到响应对象中。中的配置web.xmlcontext.xml适用于会话 cookie 之外的其他 cookie。