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.