默认情况下,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。

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

有帮助吗?

解决方案

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

配置是通过编辑meta-inf/context.xml完成​​的

u003CContextn sessionCookiePath="/something"n sessionCookieDomain=".domain.tld" />

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

其他提示

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

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

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

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

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

我还遇到了使用 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 一起使用。

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

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

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

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

解决此问题的最终方法是向 tomcat 开发人员提交补丁,向 SessionManager 类添加可配置参数。

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

使用这样的 Valve,您可以实现所需的任何进程间通信,以便同步任意数量的 tomcats/webservers/无论什么上的不同服务器、虚拟主机或 web 应用程序之间的任何状态。

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

会话处理应该被视为容器(tomcats)业务。无论您需要什么,您都应该添加,而不会干扰容器认为有必要执行的操作。

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

卡塔琳娜.jar 包含以下类: org.apache.catalina.connector.Request

请求有一个方法:

configureSessionCookie(Cookie cookie)

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

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

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top