【问题标题】:Best way for allowing subdomain session cookies using Tomcat使用 Tomcat 允许子域会话 cookie 的最佳方式
【发布时间】:2023-04-04 19:39:01
【问题描述】:

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

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

【问题讨论】:

    标签: java tomcat session cookies subdomain


    【解决方案1】:

    瓣膜技术似乎并非 100% 完美。如果你敢修改Tomcat本身:

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

    请求有一个方法:

    configureSessionCookie(Cookie cookie)
    

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

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

    似乎工作得很好。如果这可以在 tomcat 中配置就好了。

    【讨论】:

      【解决方案2】:

      我刚刚经历了所有这些,寻找一个简单的解决方案。我是先从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 高级用户,所以我确信可以对该模式进行一些优化,但到目前为止它似乎对我们有用。

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

      【讨论】:

        【解决方案3】:

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

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

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

        【讨论】:

        • +1 正是我想要的!最后他们包含了补丁。
        【解决方案4】:

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

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

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

        应将会话处理视为容器(tomcat)业务。无论您需要添加什么,都应该在不干扰容器认为必须执行的操作的情况下添加。

        【讨论】:

          【解决方案5】:

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

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

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

          【讨论】:

            猜你喜欢
            • 2014-08-03
            • 1970-01-01
            • 2010-10-13
            • 1970-01-01
            • 2021-10-20
            • 2016-08-20
            • 1970-01-01
            相关资源
            最近更新 更多