Java 使用 Tomcat 允许子域会话 cookie 的最佳方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/82645/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Best way for allowing subdomain session cookies using Tomcat
提问by Andrew Ingram
By default tomcat will create a session cookie for the current domain.
默认情况下,tomcat 将为当前域创建一个会话 cookie。
If you are on www.example.com, your cookie will be created for www.example.com (will only work on www.example.com). Whereas for example.com it will be created for .example.com (desired behaviour, will work on any subdomain of example.com as well as example.com itself).
如果您在 www.example.com 上,则将为 www.example.com 创建您的 cookie(仅适用于 www.example.com)。而对于 example.com,它将为 .example.com 创建(所需的行为,将适用于 example.com 的任何子域以及 example.com 本身)。
I've seen a few Tomcat valves which seem to intercept the creation of session cookies and create a replacement cookie with the correct .example.com domain, however none of them seem to work flawlessly and they all appear to leave the existing cookie and just create a new one. This means that two JSESSIONID cookies are being sent with each request.
我见过一些 Tomcat 阀门,它们似乎拦截了会话 cookie 的创建并使用正确的 .example.com 域创建了一个替换 cookie,但是它们似乎都没有完美地工作,而且它们似乎都离开了现有的 cookie,只是创建一个新的。这意味着每个请求都会发送两个 JSESSIONID cookie。
I was wondering if anybody has a definitive solution to this problem.
我想知道是否有人对这个问题有明确的解决方案。
采纳答案by mkvalsvik
This is apparently supported via a configuration setting in 6.0.27 and onwards:
这显然是通过 6.0.27 及以后的配置设置来支持的:
Configuration is done by editing META-INF/context.xml
<Context sessionCookiePath="/something" sessionCookieDomain=".domain.tld" />
通过编辑 META-INF/context.xml 完成配置
<Context sessionCookiePath="/something" sessionCookieDomain=".domain.tld" />
回答by Dave Cheney
I've run into this at $DAYJOB. In my case I wanted to implement SSL signon then redirect to a non SSL page. The core problem in tomcat is the method (from memory) SessionManager.configureSessionCookie which hard codes all the variables you would like to get access to.
我在 $DAYJOB 遇到过这个问题。就我而言,我想实现 SSL 登录,然后重定向到非 SSL 页面。tomcat 的核心问题是方法(从内存中)SessionManager.configureSessionCookie,它硬编码了您想要访问的所有变量。
I came up with a few ideas, including a particularly egregious hack using mod_headers in apache to rewrite the cookie based on regex substitution.
我提出了一些想法,包括在 apache 中使用 mod_headers 重写基于正则表达式替换的 cookie 的特别令人震惊的 hack。
The definative way to solve this would be to submit a patch to the tomcat developers that adds configurable parameters to the SessionManager class.
解决此问题的决定性方法是向 tomcat 开发人员提交补丁,将可配置参数添加到 SessionManager 类。
回答by Olaf Kock
As a session (and its Id) is basically considered of value only for the issueing application, you may rather look for setting an additional cookie. Have a look at Tomcats SingleSignOnValve, providing the extra-Cookie JSESSIONIDSSO (note the ...SSO) for the server path "/" instead of "/applicationName" (as JSESSIONID cookies are usually set).
由于会话(及其 Id)基本上仅被视为对发布应用程序有价值,因此您可能宁愿寻找设置额外的 cookie。看看Tomcats SingleSignOnValve,为服务器路径“/”而不是“/applicationName”提供额外的Cookie JSESSIONIDSSO(注意...SSO)(因为通常设置JSESSIONID cookie)。
With such a Valve you may implement any interprocess communication you need in order to synchronize any state between different servers, virtual hosts or webapps on any number of tomcats/webservers/whatever.
使用这样的 Valve,您可以实现您需要的任何进程间通信,以便在任意数量的 tomcats/webservers/任何数量的不同服务器、虚拟主机或 web 应用程序之间同步任何状态。
Another reason why you cannot use tomcats session cookie for your own purposes is, that multiple webapps on the same host have different session ids. E.g. there are different cookies for "/webapp1" and "/webapp2". If you provide "/webapp1"'s cookie to "/webapp2", this wouldn't find the session you referenced, invalidate your session+cookie and set its own new one. You'd have to rewrite all of tomcats session handling to accept external session id values (bad idea securitywise) or to share a certain state among applications.
您不能出于自己的目的使用 tomcats 会话 cookie 的另一个原因是,同一主机上的多个 web 应用程序具有不同的会话 ID。例如,“/webapp1”和“/webapp2”有不同的cookie。如果您将“/webapp1”的 cookie 提供给“/webapp2”,这将找不到您引用的会话,使您的会话 + cookie 无效并设置自己的新 cookie。您必须重写所有 tomcats 会话处理以接受外部会话 id 值(安全方面的坏主意)或在应用程序之间共享某个状态。
Session handling should be considered the containers (tomcats) business. Whatever else you need you should add without interfering with what the container believes is necessary to do.
会话处理应该考虑容器(tomcats)业务。无论你需要什么,你都应该添加,而不要干扰容器认为有必要做的事情。
回答by Olaf Kock
The valve techniques do not seem to be 100% perfect. If you dare to modify Tomcat itself:
阀门技术似乎不是 100% 完美的。如果你敢修改Tomcat本身:
catalina.jarcontains the following class: org.apache.catalina.connector.Request
catalina.jar包含以下类:org.apache.catalina.connector.Request
The Request has a method:
请求有一个方法:
configureSessionCookie(Cookie cookie)
For our environment it was best to just hardcode it, but you could do more fancy logic:
对于我们的环境,最好只是对其进行硬编码,但您可以执行更多奇特的逻辑:
cookie.setDomain(".xyz.com");
Seems to work perfectly. Would be nice if this was configurable in tomcat.
似乎完美地工作。如果这可以在 tomcat 中配置就好了。
回答by Jason Butler
I have just gone through all of this looking for a simple solution. I started looking at it from the tomcat perspective first.
我刚刚经历了所有这些寻找一个简单的解决方案。我先从tomcat的角度开始看。
Tomcat does not give direct access to configuring the domain cookie for the session, and I definitely did not want to custom patch tomcat to fix that problem as shown in some other posts.
Tomcat 不提供为会话配置域 cookie 的直接访问权限,而且我绝对不想自定义补丁 tomcat 来解决该问题,如其他一些帖子所示。
Valves in tomcat also seems to be a problem solution due to the limitations on accessing headers & cookies built into the Servlet specification. They also fail completely if the http response is commited before it gets passed to your valve.
由于访问 Servlet 规范中内置的标头和 cookie 的限制,tomcat 中的阀门似乎也是一个问题解决方案。如果 http 响应在传递到您的阀门之前提交,它们也会完全失败。
Since we proxy our requests through Apache, I then moved onto how to use apache to fix the problem instead.
由于我们通过 Apache 代理我们的请求,然后我转向如何使用 apache 来解决问题。
I first tried the mod_proxy directive ProxyPassReverseCookieDomain, but it does not work for JSESSIONID cookies because tomcat does not set the domain attribute and ProxyPassReverseCookieDomain cannot work without some sort of domain being part of the cookie.
我首先尝试了 mod_proxy 指令 ProxyPassReverseCookieDomain,但它不适用于 JSESSIONID cookie,因为 tomcat 没有设置域属性,并且 ProxyPassReverseCookieDomain 不能在没有某种域作为 cookie 的一部分的情况下工作。
I also came across a hack using ProxyPassReverseCookiePath where they were rewriting the path to add a domain attribute to the cookie, but that felt way to messy for a production site.
我还遇到了一个使用 ProxyPassReverseCookiePath 的黑客攻击,他们正在重写路径以将域属性添加到 cookie,但这对于生产站点来说感觉很混乱。
I finally got it to work by rewriting the response headers using the mod_headers module in apache as mentioned by Dave above.
我终于通过使用上面 Dave 提到的 apache 中的 mod_headers 模块重写响应头来让它工作。
I have added the following line inside the virtual host definition:
我在虚拟主机定义中添加了以下行:
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)[^;,]*?)*)(,|$)" "; Domain=.example.com"
The above should all be a single line in the config. It will replace any JSESSIONID cookies domain attribute with ".example.com". If a JSESSIONID cookie does not contain a domain attribute, then the pattern will add one with a value of ".example.com". As a bonus, this solution does not suffer from the double JSESSION cookies problem of the valves.
以上应该都是配置中的一行。它将用“.example.com”替换任何 JSESSIONID cookie 域属性。如果 JSESSIONID cookie 不包含域属性,则模式将添加值为“.example.com”的域属性。作为奖励,该解决方案不会遇到阀门的双重 JSESSION cookie 问题。
The pattern should work with multiple cookies in the Set-Cookie header without affecting the other cookies in the header. It should also be modifiable to work with other cookies by changing JSESSIONID in the first part of the pattern to what ever cookie name you desire.
该模式应该与 Set-Cookie 标头中的多个 cookie 一起使用,而不会影响标头中的其他 cookie。通过将模式的第一部分中的 JSESSIONID 更改为您想要的任何 cookie 名称,它也应该是可修改的以使用其他 cookie。
I am not reg-ex power user, so I am sure there are a couple of optimisations that could be made to the pattern, but it seems to be working for us so far.
我不是 reg-ex 高级用户,所以我确信可以对模式进行一些优化,但到目前为止它似乎对我们有用。
I will update this post if I find any bugs with the pattern. Hopefully this will stop a few of you from having to go through the last couple of days worth of frustrations as I did.
如果我发现该模式有任何错误,我会更新这篇文章。希望这会阻止你们中的一些人像我一样经历过去几天的挫折。