9

这个问题让我发疯,所以也许有人可以帮助我了解问题所在。我有一个由 HAProxy 引导的 tomcat Web 应用程序。HAProxy 也在进行 SSL 卸载,并配置为使用粘性会话。我正在使用 Tomcat 的会话复制功能,它似乎工作得很好。会话出现在两个应用服务器上。

出于某种原因,Tomcat 会为每个 Web 请求生成一个新的 JSESSIONID,然后将旧会话的内容复制到新会话中。也就是说,我的会话内容还在新会话中,只是生成了一个新的ID并发回给客户端。但它只对我的 Web 应用程序执行此操作。它不会为 /manager 应用程序执行此操作。

我已经尝试了书中的每一个技巧,比如在我的 context.xml 中设置:

<Valve className="org.apache.catalina.authenticator.BasicAuthenticator" changeSessionIdOnAuthentication="false" />

并在我的 Context 元素上设置这些属性:

<Context path="/myapp" reloadable="false" override="true" useNaming="false" allowLinking="true" useHttpOnly="false" sessionCookiePath="/" sessionCookiePathUsesTrailingSlash="false">

而且,结果是一样的。Tomcat 为每个请求生成一个新的会话 id,并将旧会话的内容复制到新的 id 中。

我怀疑它与 HAProxy 有关,除了 /manager 应用程序也在 HAProxy 后面并且它没有表现出这种行为。

为什么 Tomcat 这样做,我能做些什么来防止它?

4

3 回答 3

9

原来这是由 Spring Security 引起的。我们使用的是 Spring Security 3.1x,默认情况下它将经过身份验证的凭据存储在用户的会话中。为了对抗会话固定攻击,它会自动将用户会话的内容复制到新的会话 id 并使旧会话无效。

修复方法是将以下内容添加到安全配置中的 http 元素,因为我们不需要在应用程序中使用会话:

create-session="stateless"

希望这可以帮助其他人。

于 2013-01-24T01:36:27.380 回答
4

当我在 tomcat7 服务器上刷新页面时,我在新的 id 会话中遇到了同样的问题,我只在 context.xml 中添加了这段代码:

<Valve className="org.apache.catalina.authenticator.BasicAuthenticator" changeSessionIdOnAuthentication="false" />

<Context path="/myapp" reloadable="false" override="true" useNaming="false" allowLinking="true" useHttpOnly="false" sessionCookiePath="/" sessionCookiePathUsesTrailingSlash="false">

这对我来说很好。

于 2015-01-28T21:04:19.420 回答
1

不确定您的问题到底是什么,但我会检查两件事。首先,你在tomcat中指定了jvmRoute吗?

雄猫 server.xml

<Engine name="Catalina" defaultHost="localhost" jvmRoute="machine1">

Haproxy.cfg(参考 jvmRoute)

server machine1 SERVER_IP cookie machine1 check 

Tomcat 将服务器的名称附加到 cookie,因此不设置可能会导致问题。

要检查的另一件事是确保您将此行添加到您web.xmlweb-app部分

<distributable />
于 2013-01-22T19:48:16.617 回答