如何限制每个用户只有一个会话并阻止后续登录尝试?

abi*_*eez 4 spring spring-security

并发控制的默认行为是使原始会话到期.但是,我想阻止使用相同凭据登录的第二个用户显示消息"用户已登录".我怎么能做到这一点?

以下是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>
Run Code Online (Sandbox Code Playgroud)

(更新)我的最终弹簧安全配置:

<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>
Run Code Online (Sandbox Code Playgroud)

Xae*_*ess 10

解决方案在文档中:

通常您更愿意阻止第二次登录,在这种情况下您可以使用

<http>
  ...
  <session-management>
      <concurrency-control max-sessions="1" error-if-maximum-exceeded="true" />
  </session-management>
</http>
Run Code Online (Sandbox Code Playgroud)

然后将拒绝第二次登录."被拒绝"是指用户将被发送到使用authentication-failure-urlif表单的登录.如果第二次认证是通过另一种非交互式机制发生的,例如"记住我",则会向客户端发送"未授权"(402)错误.如果您想要使用错误页面,则可以将该属性添加session-authentication-error-urlsession-management元素中.

所以基本上设置error-if-maximum-exceeded"true"和删除expired-url属性<concurrency-control>.

  • 它也对我有帮助,但是我仍然希望在浏览器关闭/挂起时销毁会话。 (2认同)