Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to limit only one session per user and block the subsequent login attempt?

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:

<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:

<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>
like image 920
abiieez Avatar asked Dec 21 '22 14:12

abiieez


1 Answers

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-url if 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 attribute session-authentication-error-url to the session-management element.

So basically set error-if-maximum-exceeded to "true" and remove expired-url attribute from <concurrency-control>.

like image 157
Xaerxess Avatar answered Dec 28 '22 06:12

Xaerxess