27

默认情况下,tomcat 将为当前域创建一个会话 cookie。

如果您在 www.example.com,您的 cookie 将为 www.example.com 创建(仅适用于 www.example.com)。而对于 example.com,它将为 .example.com 创建(所需的行为将适用于 example.com 的任何子域以及 example.com 本身)。

我见过一些 Tomcat 阀门,它们似乎拦截了会话 cookie 的创建并使用正确的 .example.com 域创建了一个替换 cookie,但是它们似乎都没有完美地工作,它们似乎都离开了现有的 cookie,只是创建一个新的。这意味着每个请求都会发送两个 JSESSIONID cookie。

我想知道是否有人对这个问题有明确的解决方案。

4

5 回答 5

33

这显然是通过 6.0.27 及更高版本中的配置设置支持的:

通过编辑 META-INF/context.xml 完成配置

<上下文 sessionCookiePath="/something" sessionCookieDomain=".domain.tld" />

https://issues.apache.org/bugzilla/show_bug.cgi?id=48379

于 2010-08-06T19:56:13.123 回答
6

我刚刚经历了所有这些寻找一个简单的解决方案。我首先从tomcat的角度开始看它。

Tomcat 不提供直接访问为会话配置域 cookie 的权限,我绝对不想自定义补丁 tomcat 来解决该问题,如其他一些帖子所示。

由于访问 Servlet 规范中内置的标头和 cookie 的限制,tomcat 中的阀门似乎也是一个问题解决方案。如果 http 响应在传递到您的阀门之前提交,它们也会完全失败。

由于我们通过 Apache 代理我们的请求,因此我转而讨论如何使用 apache 来解决问题。

我首先尝试了 mod_proxy 指令 ProxyPassReverseCookieDomain,但它不适用于 JSESSIONID cookie,因为 tomcat 没有设置域属性,并且如果没有某种域作为 cookie 的一部分,ProxyPassReverseCookieDomain 就无法工作。

我还遇到了一个使用 ProxyPassReverseCookiePath 的黑客攻击,他们正在重写路径以向 cookie 添加域属性,但这对于生产站点来说感觉很混乱。

我终于通过使用上面 Dave 提到的 apache 中的 mod_headers 模块重写响应头来让它工作。

我在虚拟主机定义中添加了以下行:

Header edit Set-Cookie "(JSESSIONID\s?=[^;,]+?)((?:;\s?(?:(?i)Comment|Max-Age|Path|Version|Secure)[^;,]*?)*)(;\s?(?:(?i)Domain\s?=)[^;,]+?)?((?:;\s?(?:(?i)Comment|Max-Age|Path|Version|Secure)[^;,]*?)*)(,|$)" "$1$2; Domain=.example.com$4$5"

以上都应该是配置中的一行。它将任何 JSESSIONID cookie 域属性替换为“.example.com”。如果 JSESSIONID cookie 不包含域属性,则该模式将添加一个值为“.example.com”的。作为奖励,此解决方案不会受到阀门的双 JSESSION cookie 问题的影响。

该模式应该适用于 Set-Cookie 标头中的多个 cookie,而不会影响标头中的其他 cookie。通过将模式第一部分中的 JSESSIONID 更改为您想要的任何 cookie 名称,它也应该可以修改以与其他 cookie 一起使用。

我不是 reg-ex 高级用户,所以我确信可以对模式进行一些优化,但到目前为止它似乎对我们有用。

如果我发现该模式有任何错误,我会更新这篇文章。希望这将阻止你们中的一些人像我一样经历过去几天的挫折。

于 2010-05-25T06:56:03.967 回答
1

我在 $DAYJOB 遇到过这个问题。就我而言,我想实现 SSL 登录,然后重定向到非 SSL 页面。tomcat 的核心问题是方法(从内存中) SessionManager.configureSessionCookie 硬编码您想要访问的所有变量。

我想出了一些想法,包括在 apache 中使用 mod_headers 来基于正则表达式替换重写 cookie 的一个特别令人震惊的 hack。

解决这个问题的决定性方法是向 tomcat 开发人员提交一个补丁,将可配置参数添加到 SessionManager 类。

于 2008-09-17T13:11:02.483 回答
1

由于会话(及其 Id)基本上只对发布应用程序有价值,您可能宁愿寻找设置额外的 cookie。看看 Tomcats SingleSignOnValve,它为服务器路径“/”而不是“/applicationName”(通常设置 JSESSIONID cookie)提供额外的 Cookie JSESSIONIDSSO(注意 ...SSO)。

使用这样的 Valve,您可以实现所需的任何进程间通信,以便在任意数量的 tomcats/webservers/其他任何东西上同步不同服务器、虚拟主机或 webapps 之间的任何状态。

您不能出于自己的目的使用 tomcats 会话 cookie 的另一个原因是,同一主机上的多个 Web 应用程序具有不同的会话 ID。例如,“/webapp1”和“/webapp2”有不同的cookies。如果您将“/webapp1”的 cookie 提供给“/webapp2”,这将找不到您引用的会话,使您的会话+cookie 无效并设置自己的新会话。您必须重写所有 tomcats 会话处理以接受外部会话 id 值(安全方面的坏主意)或在应用程序之间共享某个状态。

会话处理应被视为容器(tomcats)业务。无论你需要什么,你都应该在不干扰容器认为必须做的事情的情况下添加。

于 2008-09-17T13:15:20.850 回答
1

阀门技术似乎不是 100% 完美的。如果你敢修改Tomcat本身:

catalina.jar包含以下类:org.apache.catalina.connector.Request

请求有一个方法:

configureSessionCookie(Cookie cookie)

对于我们的环境,最好只对其进行硬编码,但您可以做更多奇特的逻辑:

cookie.setDomain(".xyz.com");

似乎工作完美。如果这可以在 tomcat 中配置,那就太好了。

于 2009-03-11T05:40:39.220 回答