Spring 4 - 会话管理
Posted
技术标签:
【中文标题】Spring 4 - 会话管理【英文标题】:Spring 4 - Session Management 【发布时间】:2016-10-26 15:20:12 【问题描述】:大家好,
我目前正在我们公司内部运行一个部署在 tomcat 8 服务器上的企业 Spring Web 应用程序。
现在,一些用户报告说有时他们无法连接,因为登录页面上显示了登录错误。
嗯,这就是为什么:
我的会话配置是这样设置的:
<session-management>
<concurrency-control max-sessions="5"
error-if-maximum-exceeded="true" expired-url="/login"
session-registry-alias="sessionRegistry"/>
</session-management>
<form-login login-processing-url="/login"
login-page="/login"
authentication-failure-url="/login_error" />
<logout logout-url="/logout" logout-success-url="/login"
invalidate-session="true"/>
会话超时设置为 4 小时:
<session-timeout>240</session-timeout>
当用户请求登录页面时,带有 csfr 令牌的会话存储在服务器端。
当用户注销时,他的会话无效并被重定向到登录页面,因为带有 csfr-token 的新会话再次存储在服务器端。
当用户已经有 5 个会话(不同的浏览器、设备、奇怪的客户端行为)并尝试第 6 次登录时 - 登录被拒绝,因为超出了会话最大值。
现在在最坏的情况下,有 5 个会话,只有 csrf-token 存储在服务器端,假设是 avg。 3小时的生命周期,阻止用户再次连接。
请告诉我有比以下更好的解决方案:
max-sessions="biggerNumber"
感谢您的阅读...
【问题讨论】:
【参考方案1】:您可以结合两种可能性:
增加并发会话数 减少会话超时(30 分钟已经很大了)但是您还有一个更激进的方法:更改策略以便不拒绝新连接而是撤销最旧的连接。 spring-security允许开箱即用,只需从concurrency-control
标签中删除error-if-maximum-exceeded="true"
即可:
<session-management>
<concurrency-control max-sessions="5"
expired-url="/login"
session-registry-alias="sessionRegistry"/>
</session-management>
【讨论】:
您好,非常感谢您的回复。这正是我一直在寻找的。我将删除 error-if-maximum-exceeded,因此最旧的会话被撤销。我在阅读安全文档时没有弄清楚这一点 - 所以感谢您说清楚!会话超时确实非常大 - 但它是这样要求的。【参考方案2】:我检查了下面的 spring 文档并进行了测试。
http://docs.spring.io/spring-security/site/docs/current/reference/html/session-mgmt.html#concurrent-sessions
事实证明,你必须在你的 web.xml 中添加这个
<listener>
<listener-class>
org.springframework.security.web.session.HttpSessionEventPublisher
</listener-class>
</listener>
此侦听器将在注销时删除连接到主体实例的会话。否则,即使在注销后会话仍然连接到主体实例。这就是为什么您会不断收到错误消息“超出此主体的 XX 的最大会话数”。
【讨论】:
以上是关于Spring 4 - 会话管理的主要内容,如果未能解决你的问题,请参考以下文章
Spring Security 会话管理会话固定保护不起作用
spring boot整合 spring security之会话管理
Spring 安全会话管理和 Spring MVC 视图解析器错误