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

时间:2016-11-22 23:48:39

标签: java session tomcat cookies

我正在尝试在我的应用程序的web.xml中设置cookie路径(如建议的here):

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

因此,我将两个相同的Web应用程序分别部署到localhost:8080/application-alocalhost: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());
      }
  }
}

我将应用程序部署到Tomcat 8.5容器(尝试使用Tomcat 9,行为也一样)。当我使用浏览器访问application-a时,我看到的是:

enter image description here

...在我读过的Tomcat日志中:

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

到目前为止一切顺利。当我在这里访问application-b时,我看到的是:

enter image description here

...和Tomcat日志显示:

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

这也很好解释herein this answer并引用:

  

SRV.7.3会话范围

     

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

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

然而,当我现在回到我的application-a时,我发现由于为cookie路径配置了/值,它现在尝试使用JSESSIONID值集通过application-b,当然它的servlet在它自己的上下文中找不到这样的会话对象(application-a),因此创建了JSESSIONID cookie的新值。当我在两个应用程序之间来回切换时,无限制地使application-b应用程序的会话无效等等无处不在。

所以我的问题是:

1鉴于上述行为,两个应用程序似乎不可能使用相同的JSESSIONID cookie值作为其各自HttpSession对象的键。事实上,不仅HttpSession对象总是不同并且在应用程序(servlet上下文)级别作用域,而且在实践中,JSESSIONID值必须不同。这是对的吗?

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

  

底层机制,例如用于建立的cookie   会话,对于不同的上下文[...]

可以是相同的

我可以想象上面唯一可以实现的方法是有一种方法可以硬编码地提供在创建新会话对象时使用的JSESSIONID值吗?但我没有看到API。

3我是否有办法在&lt; session-config&gt;中使用/路径在应用程序之间共享其他Cookie XML元素但没有/路径适用于JSESSIONID Cookie?换句话说,&lt; session-config&gt;适用于应用程序的所有cookie或仅用于会话跟踪的cookie? (JSESSIONID)?

1 个答案:

答案 0 :(得分:1)

经过进一步的实验并从this answer获取提示,似乎对于所有Web应用程序使用相同的JSESSIONID,必须在context.xml中设置以下属性:

<Context ... sessionCookiePath="/">

Tomcat范围的context.xml 特定于WAR的context.xml。显然忽略了WAR的web.xml中配置的<cookie-config><path>值。

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