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

问题描述:

默认情况下,tomcat将为当前域创建一个会话cookie。允许使用Tomcat的子域会话cookie的最佳方式

如果您在www.example.com上,您的Cookie将为www.example.com创建(仅适用于www.example.com)。而example.com则会为.example.com创建(期望的行为,可以在example.com的任何子域以及example.com本身上运行)。

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

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

这显然是通过6.0中的配置设置支持的。27及以后: “使用domain.tld”

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

<语境 sessionCookiePath = “/某事” sessionCookieDomain =/>

完成

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

+0

+1正是我在找的东西!最后他们包括了这个补丁。 – Kdeveloper 2010-11-12 10:32:51

我碰到过这个$ DAYJOB。在我的情况下,我想实现SSL登录,然后重定向到一个非SSL页面。 tomcat中的核心问题是SessionManager.configureSessionCookie方法(来自内存),它会对您希望访问的所有变量进行硬编码。

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

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

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

有了这样一个Valve,你可以实现任何你需要的进程间通信,以便同步任何数量的tomcats/webservers /不同服务器,虚拟主机或webapps之间的任何状态。

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

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

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

catalina.jar包含以下类:org.apache.catalina.connector。请求

请求有一个方法:

configureSessionCookie(Cookie cookie) 

对于我们的环境是最好的,只是硬编码的,但你可以做更看中的逻辑:

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

似乎完美地工作。如果这可以在tomcat中配置,会很好。

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

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

由于访问头文件& cookie内置于Servlet规范中的限制,tomcat中的阀门似乎也是一个问题解决方案。如果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 cookie域属性。如果JSESSIONID cookie不包含域属性,则该模式将添加一个值为“.example.com”的模式。作为奖励,这种解决方案不会受到阀门的双JSESSION饼干问题的困扰。

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

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

我会更新这个帖子,如果我发现任何错误的模式。希望这会阻止你们中的一些人不必像我一样经历过去几天的挫折。