Tomcat 为每个请求创建一个新会话

Posted

技术标签:

【中文标题】Tomcat 为每个请求创建一个新会话【英文标题】:Tomcat create a new session for every request 【发布时间】:2011-05-15 08:13:01 【问题描述】:

我现在正在解决这个问题 2 天,我希望这里的任何人都有类似的问题和解决方案。

问题: 这是一个 Spring MVC (2.5.6.) Web 应用程序,在 Tomcat 6 中运行。 当请求开始页面时,它会将客户重定向到 JSP 页面(通过使用 html 的元刷新标签),该页面会使用大量 Ajax 请求(框架:原型)加载其内容。问题是 Tomcat 为每个 AJAX 请求(大约 67 个会话)创建一个新会话。 我的第一个想法是 Session Cookie 是在加载起始页面后存储的,Ajax 请求会强制 Tomcat 创建一个新会话。我的方法是手动创建会话 cookie,但这没有任何区别。 有趣的是,它可以在其他一些 tomcat 实例中工作,但不能在集成测试所需的环境中工作。在我看来,这是一个 Tomcat 配置问题。

在使用 Firebug 进一步调查后,我发现 Tomcat 会为每个请求创建一个新的 Session,即使将正确的 JSESSIONID 传输给它 (50B5EA0BCFE811C744CE9C1F9EDE0097):

Request Header 1: 
Cookie JSESSIONID=F3206CBF2C961E125821FF22FA31A02D

Response Header 1:
Set-Cookie JSESSIONID=49E000B4D6880F4F94531AB9C78DB667; Path=/JOCA-Music-Portal   JSESSIONID=50B5EA0BCFE811C744CE9C1F9EDE0097; Path=/JOCA-Music-Portal

Request Header 2:
Cookie JSESSIONID=50B5EA0BCFE811C744CE9C1F9EDE0097

Response Header 2:
Set-Cookie JSESSIONID=DCCA2D1B98D11223A6B8855800276E27; Path=/JOCA-Music-Portal

更新:进一步调查将问题隔离到 Tomcat 领域配置。我们使用 JDBC Realm 进行登录。当登录被停用时,只会创建一个会话。 如果它被激活,Tomcat 会创建无效/过期的会话,这就是每个请求都会创建一个新会话的原因。但是为什么 Tomcat 会这样呢?

我真的很绝望,所以任何想法/提示/解决方案都非常感谢。

非常感谢

【问题讨论】:

【参考方案1】:

您可以尝试在您的客户端和服务器之间使用analyze the HTTP traffic。确保在请求和响应中正确设置了 Cookie 标头。

如果使用火狐,可以尝试使用Firebug进行调试。

【讨论】:

首先非常感谢您的回答。 cookie 标头设置正确,我用 Firebug 进行了检查。我忘了提到在其他一些环境中它可以正常工作,但在集成测试环境中却没有。 Tomcat 配置的<context> 部分中是否有cookies=falseuseHttpOnly 的值是多少? 不,我没有在 /META-INF/context.xml 中定义任何上下文部分,因此未设置 cookies 和 useHttpOnly。我应该定义一个 context.xml 吗? 我认为没有必要。根据文档tomcat.apache.org/tomcat-6.0-doc/config/context.html,您应该可以使用默认值。也许这些值已从 server.xml 中的默认值更改。您描述的行为听起来像 useHttpOnly 在某些配置文件中设置为 true(使用 Tomcat,您可以在很多地方设置此信息,请参阅上述文档) 好的,非常感谢您的支持,我将定义一个 context.xml 明确地将 useHttpOnly 设置为 false 并在此处发布结果。【参考方案2】:

我们最近在开发的应用程序中遇到了同样的问题。来发现,问题是Tomcat被修改以帮助防止会话固定攻击。默认情况下,在身份验证时会创建一个新的会话 ID。这从 6.0.21 开始。查看上下文配置选项“changeSessionIdOnAuthentication”(tomcat 错误/问题是https://issues.apache.org/bugzilla/show_bug.cgi?id=45255)。

【讨论】:

非常感谢! - 我会检查一下;)【参考方案3】:

我们遇到了同样的问题,但在使用自定义 EXTERNALSSO 身份验证时。解决方案是在继承自 org.apache.catalina.authenticator.AuthenticatorBase 的类的构造函数中显式关闭它:

super.setChangeSessionIdOnAuthentication(false);

【讨论】:

以上是关于Tomcat 为每个请求创建一个新会话的主要内容,如果未能解决你的问题,请参考以下文章

Express.js/Passport 应用程序为每个请求创建新会话,尽管请求标头中有会话 ID

移动浏览器会针对每个请求启动新会话

如何防止 Jetty/GAE 为不同的上下文路径创建新会话?

org.openqa.selenium.SessionNotCreatedException:无法创建新会话。 (原始错误:请求了一个新会话,但一个正在进行中)

为啥在我登录之前创建了一个新会话?

使用_IECreate()创建新会话