Restricting concurrent sessions for a single user using Grails and Spring Security

04 / Dec / 2014 by Dhanendra Kumar 3 comments

Restricting concurrent sessions for a single user is a very common requirement for any software tool which requires licensing based on number of users.

You can read about how we can manage (or allow) concurrent sessions with Grails 2 using Spring security plugin in this awesome concise blog here.

let us see how we can allow or restrict the concurrent sessions for the different users i.e. restricting the concurrent sessions for the some users and allowing multiple sessions for a specific set of users.

In our application, we have ‘Executive Users’ and ‘Administrator’ where the ‘Executive Users’ can not have concurrent sessions but the ‘Administrators’ can have multiple concurrent sessions i.e. they can login simultaneously from different clients/devices with the same username.

In order to achieve this (restriction and allowing of concurrent sessions for different sets of users), we need to do the following steps:

  1. First off we have to extend the org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy class and override the getMaximumSessionsForThisUser() method

    [java]
    import org.springframework.security.core.session.SessionRegistry
    import org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy

    class MyConcurrentSessionControlStrategy extends ConcurrentSessionControlStrategy {

    MyConcurrentSessionControlStrategy(SessionRegistry sessionRegistry) {
    super(sessionRegistry)
    }

    protected int getMaximumSessionsForThisUser(org.springframework.security.core.Authentication authentication) {
    Long maximumSession = 1
    if (Role.ROLE_ADMIN in authentication.authorities*.authority) {
    maximumSession = -1
    }
    return maximumSession;
    }
    }
    [/java]

    Here, we are giving infinite concurrent sessions to the users with role ‘Administrators’ whereas all the other users can have only one session. The values given to the maximumSession can be:

    -1 for infinite session,
    +ve ‘n’ value for ‘n’ number of sessions allowed; the value 0 is not allowed.

  2. Update resources.groovy to include your own version of ConcurrentSessionControlStrategy class i.e. MyConcurrentSessionControlStrategy:

[java]

import org.springframework.security.core.session.SessionRegistryImpl
import org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy
import org.springframework.security.web.session.ConcurrentSessionFilter

beans = {
sessionRegistry(SessionRegistryImpl)

concurrencyFilter(ConcurrentSessionFilter) {
sessionRegistry = sessionRegistry
logoutHandlers = [ref("rememberMeServices"), ref("securityContextLogoutHandler")]
expiredUrl = ‘/login/concurrentSession’
}

concurrentSessionControlStrategy(MyConcurrentSessionControlStrategy, sessionRegistry) {
alwaysCreateSession = true
exceptionIfMaximumExceeded = false
maximumSessions = 1
}
}

[/java]

 

Lets take a look on the beans that we are injecting

  1. sessionRegistry: We must use the SessionRegistryImpl provided by Spring security plugin.

  2. concurrencyFilter:

    1. sessionRegistry: Setting sessionRegistry bean to use overridden implementation to ensure that every registered session’s “last updated” time is always correct and check if the session is expired then call the configured logout handlers.

    2. logoutHandlers: Updating logout handlers with rememberMeServices and securityContextLogoutHandler – By default only securityContextLogoutHandler is registered. But we also need to add rememberMeServices bean to ensure that “remember me cookie” is also expired if user concurrent session exceeds the maximumSession otherwise this cookie creates a new session and invalidate the other one.

    3. expiredUrl: This field is used to redirect the user to this url if the number of active sessions for this user exceeds the maximum allowed limit.

  3. concurrentSessionControlStrategy:

    1. alwaysCreateSession: Set the value of this field to true in order to allow concurrent sessions.

    2. exceptionIfMaximumExceeded:

      1. Set it to “true” to invalidate the new session that we are creating if the concurrent sessions exceed the maximumSession.

      2. Set it to “false” to invalidate the oldest session that was created for the user if the concurrent sessions exceed the maximumSession.

    3. maximumSession: Set the maximum concurrent sessions allowed for a user.

 

By doing this, Spring security will restrict the concurrent logins for the users and also ensure that users with the specific role only can have multiple sessions.

Hope this helps !!!

FOUND THIS USEFUL? SHARE IT

comments (3)

  1. Carlos

    The example does not work for me. Besides, ConcurrentSessionControlStrategy is deprecated. Can you update with a new version?
    Thanks.

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *