You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@shiro.apache.org by Narcom <na...@yahoo.com> on 2009/12/01 21:39:25 UTC

Concurrent Session Control

what if I wish to place constraints on a single user's ability to log in to
my application. Similar like in SpringSecurity
http://static.springsource.org/spring-security/site/docs/2.0.x/reference/ns-config.html#ns-concurrent-session.
smth like <concurrent-session-control max-sessions="1" /> ?

how to implement it in Shiro. Could someone tell me where to start from?

-- 
View this message in context: http://n2.nabble.com/Concurrent-Session-Control-tp4096145p4096145.html
Sent from the Shiro User mailing list archive at Nabble.com.

Re: Concurrent Session Control

Posted by lev <di...@amdocs.com>.
my two cents,

I did use Narcom's project and must say it is a good starting project for
someone who is new to Shiro as this project gives an idea of personalised
domain,and use of Shiro as remoted IDM product.

I cleaned not needed classes/packages/conf files and extended narcom's
project with a Thrift client and JPA datalayer.

seems like nice idea to put this project as initial reference in shiro site.

Regards



Narcom wrote:
> 
> if you configure concurent sesssion restriction, for example, to 1. It
> means that user with user name, for example, "USERONE" in any period of
> time will be allowed to have only one session. in Shiro terminology only
> one Session in any period of time will return getPrimaryPrincipal as
> "USERONE".
> in general there should be two option to select:
> 1. if user "USERONE" already logged in then block new login attempts with
> this username
> 2. login in user with username "USERONE" and then check if there other
> clients logged in with this username. if so invalidate their sessions.
> 
> option 2 is the most used. 
> 
> If we use shiro "http" session mode then as I understand we use default
> Tomcat session implementation. To achive this behavior in Tomcat we need
> implement special listener HttpSessionListener. it will allow us to catch
> such events as session-create and session-destroy. using this listener we
> can store all needed information to implement "concurent sesssion control"
> 
> If we use shiro "native" session mode then as I understand it is better to
> use ehCahe. in this case we can directly access cache via cacheManager. 
> 
> I did a little example how to enable option 2 behavior for ehCache and for
> Tomcat sessions:
> 
> this example for ehCache:
> private void removeConcurrentSessions(Subject currentUser) throws
> InvalidSessionException, CacheException {
>         String cacheName =
> ((CachingSessionDAO)((DefaultSessionManager)securityManager.getSessionManager()).getSessionDAO()).getActiveSessionsCacheName();
>         Cache cache =
> securityManager.getCacheManager().getCache(cacheName);
>         log.debug("using cache: " + cacheName);
>         Iterator iter = cache.keys().iterator();
>         while (iter.hasNext()) {
>             String sess = (String) iter.next();
>             log.debug("key: " + sess);
>             if(sess.equals(currentUser.getSession(false).getId())){
>                 log.debug("removeConcurrentSessions: skip current
> session");
>                 continue;
>             }
>             Object objKeys = cache.get(sess);
>             Session objSess = (Session) objKeys;
>             //Collection keys = objSess.getAttributeKeys();
>             if (objSess != null) {
>                 Collection keys = objSess.getAttributeKeys();
>                 for (Object obj : keys) {
>                     log.debug("key name: " + obj.toString());
>                     //SessionSubjectBinder.AUTHENTICATED_SESSION_KEY -
> bolean
>                     //SessionSubjectBinder.PRINCIPALS_SESSION_KEY -
> PrincipalCollection
>                 }
>                 PrincipalCollection principalCollection =
> (PrincipalCollection)
> objSess.getAttribute(SessionSubjectBinder.PRINCIPALS_SESSION_KEY);
>                 if (principalCollection != null) {
>                     for (Object obj : principalCollection.asList()) {
>                         log.debug("principal name: " + obj.toString());
>                         if (obj.toString().equals("user1")) {
>                             log.debug("user user1 already logged in.
> remove its previous session");
>                             cache.remove(sess);
>                         }
>                     }
>                 }
>             }
>             log.debug("");
>         }
>     }
> 
> but all this solution is very different. they works but they are not part
> of the framework 
> 
> also I uploaded whole my test project to
> http://kenai.com/projects/shirospring. it test project covers
> Shiro, Spring, Spring remoting, Tomcat and EhCache integration. +
> Concurency session control for Shiro .
> I suggest that you could take it as example, clear some code/style and put
> it as usage example in Shiro distribution or somehow put it on your site
> as example.  
> 
> 
>  
> 
> 
> 

-- 
View this message in context: http://n2.nabble.com/Concurrent-Session-Control-tp4096145p4131687.html
Sent from the Shiro User mailing list archive at Nabble.com.

Re: Concurrent Session Control

Posted by Narcom <na...@yahoo.com>.
if you configure concurent sesssion restriction, for example, to 1. It means
that user with user name, for example, "USERONE" in any period of time will
be allowed to have only one session. in Shiro terminology only one Session
in any period of time will return getPrimaryPrincipal as "USERONE".
in general there should be two option to select:
1. if user "USERONE" already logged in then block new login attempts with
this username
2. login in user with username "USERONE" and then check if there other
clients logged in with this username. if so invalidate their sessions.

option 2 is the most used. 

If we use shiro "http" session mode then as I understand we use default
Tomcat session implementation. To achive this behavior in Tomcat we need
implement special listener HttpSessionListener. it will allow us to catch
such events as session-create and session-destroy. using this listener we
can store all needed information to implement "concurent sesssion control"

If we use shiro "native" session mode then as I understand it is better to
use ehCahe. in this case we can directly access cache via cacheManager. 

I did a little example how to enable option 2 behavior for ehCache and for
Tomcat sessions:

this example for ehCache:
private void removeConcurrentSessions(Subject currentUser) throws
InvalidSessionException, CacheException {
        String cacheName =
((CachingSessionDAO)((DefaultSessionManager)securityManager.getSessionManager()).getSessionDAO()).getActiveSessionsCacheName();
        Cache cache = securityManager.getCacheManager().getCache(cacheName);
        log.debug("using cache: " + cacheName);
        Iterator iter = cache.keys().iterator();
        while (iter.hasNext()) {
            String sess = (String) iter.next();
            log.debug("key: " + sess);
            if(sess.equals(currentUser.getSession(false).getId())){
                log.debug("removeConcurrentSessions: skip current session");
                continue;
            }
            Object objKeys = cache.get(sess);
            Session objSess = (Session) objKeys;
            //Collection keys = objSess.getAttributeKeys();
            if (objSess != null) {
                Collection keys = objSess.getAttributeKeys();
                for (Object obj : keys) {
                    log.debug("key name: " + obj.toString());
                    //SessionSubjectBinder.AUTHENTICATED_SESSION_KEY -
bolean
                    //SessionSubjectBinder.PRINCIPALS_SESSION_KEY -
PrincipalCollection
                }
                PrincipalCollection principalCollection =
(PrincipalCollection)
objSess.getAttribute(SessionSubjectBinder.PRINCIPALS_SESSION_KEY);
                if (principalCollection != null) {
                    for (Object obj : principalCollection.asList()) {
                        log.debug("principal name: " + obj.toString());
                        if (obj.toString().equals("user1")) {
                            log.debug("user user1 already logged in. remove
its previous session");
                            cache.remove(sess);
                        }
                    }
                }
            }
            log.debug("");
        }
    }

but all this solution is very different. they works but they are not part of
the framework 

also I uploaded whole my test project to
http://kenai.com/projects/shirospring. it test project covers
Shiro, Spring, Spring remoting, Tomcat and EhCache integration. + Concurency
session control for Shiro .
I suggest that you could take it as example, clear some code/style and put
it as usage example in Shiro distribution or somehow put it on your site as
example.  


 


-- 
View this message in context: http://n2.nabble.com/Concurrent-Session-Control-tp4096145p4119341.html
Sent from the Shiro User mailing list archive at Nabble.com.

Re: Concurrent Session Control

Posted by Les Hazlewood <lh...@apache.org>.
I'm not entirely sure how Spring Security works, but it appears that
it checks concurrent log-ins based on a cached value in the
HttpSession.  If that's the case a simple

subject.isAuthenticated() call is good enough to determine if they've
logged in during their current session.

What exactly is your desired behavior?  Could you give a use case?

On Tue, Dec 1, 2009 at 3:39 PM, Narcom <na...@yahoo.com> wrote:
>
> what if I wish to place constraints on a single user's ability to log in to
> my application. Similar like in SpringSecurity
> http://static.springsource.org/spring-security/site/docs/2.0.x/reference/ns-config.html#ns-concurrent-session.
> smth like <concurrent-session-control max-sessions="1" /> ?
>
> how to implement it in Shiro. Could someone tell me where to start from?
>
> --
> View this message in context: http://n2.nabble.com/Concurrent-Session-Control-tp4096145p4096145.html
> Sent from the Shiro User mailing list archive at Nabble.com.
>