允许使用 Tomcat 的子域会话 Cookie 的最佳方式

2022-09-01 14:22:14

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

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

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

我想知道是否有人有解决这个问题的最终解决方案。


答案 1

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

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

<Context sessionCookiePath=“/something” sessionCookieDomain=“.domain.tld” />

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


答案 2

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

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

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

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

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

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

我最终通过使用apache中的mod_headers模块重写响应标头来使其工作,如上面的Dave所述。

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

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"

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

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

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

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


推荐