spring 如何限制每个用户只能进行一个会话并阻止后续的登录尝试?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12985862/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to limit only one session per user and block the subsequent login attempt?
提问by abiieez
The default behavior of concurrency control is to expire the original session. However, I would like to block the second user which is logging in with the same credentials with displaying message "User has already logged in". How can I accomplish this ?
并发控制的默认行为是使原始会话过期。但是,我想阻止使用相同凭据登录并显示消息“用户已登录”的第二个用户。我怎样才能做到这一点?
Below is the configuration of spring-security.xml:
下面是 spring-security.xml 的配置:
<http auto-config="false" use-expressions="true">
<intercept-url pattern="/login*" access="permitAll"
requires-channel="https" />
<intercept-url pattern="/userHasLoggedIn" access="permitAll"
requires-channel="https" />
<intercept-url pattern="/j_spring_security_*" access="permitAll"
requires-channel="https" />
<intercept-url pattern="/session*" access="permitAll"
requires-channel="https" />
<form-login login-page="/login" authentication-failure-url="/loginFailed" />
<intercept-url pattern="/**" access="isAuthenticated()"
requires-channel="https" />
<session-management invalid-session-url="/sessionExpired" session-authentication-error-url="/loginAlready">
<concurrency-control error-if-maximum-exceeded="false" expired-url="/userHasLoggedIn" max-sessions="1"/>
</session-management>
<logout delete-cookies="JSESSIONID" />
</http>
(Updated)My final spring security configuration:
(更新)我最终的 spring 安全配置:
<http auto-config="false" use-expressions="true">
<intercept-url pattern="/login*" access="permitAll"
requires-channel="https" />
<form-login default-target-url="/home" login-page="/login" authentication-failure-url="/loginFailed" />
<intercept-url pattern="/**" access="isFullyAuthenticated()"
requires-channel="https" />
<session-management session-authentication-error-url="/loginFailed">
<concurrency-control expired-url="/loginFailed" error-if-maximum-exceeded="true" max-sessions="1"/>
</session-management>
<logout delete-cookies="JSESSIONID" />
</http>
回答by Xaerxess
The solution is in the documentation:
解决方案在文档中:
Often you would prefer to prevent a second login, in which case you can use
<http> ... <session-management> <concurrency-control max-sessions="1" error-if-maximum-exceeded="true" /> </session-management> </http>The second login will then be rejected. By “rejected”, we mean that the user will be sent to the
authentication-failure-urlif form-based login is being used. If the second authentication takes place through another non-interactive mechanism, such as “remember-me”, an “unauthorized” (402) error will be sent to the client. If instead you want to use an error page, you can add the attributesession-authentication-error-urlto thesession-managementelement.
通常,您希望防止第二次登录,在这种情况下,您可以使用
<http> ... <session-management> <concurrency-control max-sessions="1" error-if-maximum-exceeded="true" /> </session-management> </http>第二次登录将被拒绝。通过“拒绝”,我们的意思是
authentication-failure-url如果使用基于表单的登录,用户将被发送到。如果第二次身份验证是通过另一种非交互机制(例如“记住我”)进行的,则会向客户端发送“未授权”(402)错误。如果您想使用错误页面,则可以将属性添加session-authentication-error-url到session-management元素。
So basically set error-if-maximum-exceededto "true"and remove expired-urlattribute from <concurrency-control>.
所以基本上设置error-if-maximum-exceeded为"true"并expired-url从中删除属性<concurrency-control>。

