这个问题让我感到疯狂,所以也许有人可以帮我理解问题所在。我有一个tomcat web应用程序正面向HAProxy。 HAProxy也在进行SSL卸载,并配置为使用粘性会话。我正在使用Tomcat的会话复制功能,这似乎工作正常。会话出现在两个appservers上。
出于某种原因,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会这样做,我该怎么做才能阻止它?
答案 0 :(得分:6)
原来这是由Spring Security引起的。我们使用的是Spring Security 3.1x,默认情况下它会将经过身份验证的凭据存储在用户的会话中。并且为了对抗会话固定攻击,它会自动将用户会话的内容复制到新的会话ID,并使旧会话无效。
修复是将以下内容添加到安全配置中的http元素,因为我们不需要在我们的应用程序中使用该会话:
create-session="stateless"
希望这有助于其他人下线。
答案 1 :(得分:3)
刷新页面时,我遇到了与新ID会话相同的问题 在tomcat7服务器上,我只在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">
这对我来说很好。
答案 2 :(得分:1)
不确定您的问题究竟是什么,但我会检查两件事。首先,你是否在tomcat中指定了jvmRoute?
Tomcat server.xml
<Engine name="Catalina" defaultHost="localhost" jvmRoute="machine1">
Haproxy.cfg (引用jvmRoute)
server machine1 SERVER_IP cookie machine1 check
Tomcat将服务器的名称附加到cookie,因此不设置会导致问题。
要检查的另一件事是确保您将此行添加到web.xml
部分的web-app
<distributable />