You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@shiro.apache.org by Stephen McCants <st...@hcs.us.com> on 2013/09/27 01:31:23 UTC

Forced Logout on User ID Locked

Hello All,
     I'm working on a new problem and haven't found a good solution.
     We have the ability to lock a user's account which prevents them 
from logging in.  This is implemented in our custom Realm.  However, if 
a user is already logged in, they can continue to do things until their 
session expires or they logout.
     We'd like to be able to boot someone out immediately, but I haven't 
been able to find a good way to do this.  My main approach was to modify 
their session, but that seemed to have no effect on their Subject in 
their ThreadContext.
     Here are some of the things I tried doing to their session:

         SessionDAO sdao = DAOUtils.getFactory().getSessionDAO(); // Get 
the custom session DAO
         sdao.getActiveSessions();
         for (Session s:sessions) {
                 // Find the session based on the locked user's principal
                 s.stop();
                 sdao.update(s);
         }

Also tried:

s.setAttribute(org.apache.shiro.subject.support.DefaultSubjectContext.AUTHENTICATED_SESSION_KEY, 
false);
         sdao.update(s);

And:
         sdao.delete(s);

I also tried building a new subject from the session and logging it out:

         Subject foreignSubject = new 
Subject.Builder().session(s).buildSubject();
         foreignSubject.logout();

I think the problem is the real Subject is cached in a ThreadLocal and 
not accessible (unless the person locking the account is locking their 
own account).  The cached Subject doesn't get updated when the session 
has changed.
     Does anyone have any recommendations or even a good solution to 
this problem?  I'm sure I'm not the first to want to do this.
     Thanks in advance!

         Sincerely,
             Stephen McCants

-- 
Stephen McCants
Senior Software Engineer
Healthcare Control Systems
1-877-877-8795 x116


Re: Forced Logout on User ID Locked

Posted by versatec <ro...@versatec.de>.
"2) If the user goes through a different filter, that filter needs to be
modified as well."
Instead of modifying each filter you could just put your own small
isUserAccountLocked filter before all the other filters in shiro.ini:
/** = ssl[8181], accountLocked, authc
That way a locked account would be automatically logged out before authc
checks access. But the polling would still be needed which I agree is ugly.



--
View this message in context: http://shiro-user.582556.n2.nabble.com/Forced-Logout-on-User-ID-Locked-tp7579189p7579219.html
Sent from the Shiro User mailing list archive at Nabble.com.

Re: Forced Logout on User ID Locked

Posted by Stephen McCants <st...@hcs.us.com>.
Hi Jared,

I tried the permissions change, but this caused other problems. Namely:

1) Permission would be shown wrong to an administrator looking at a 
locked account.
2) User with a locked account would get strange page loads.  Some things 
require permissions, others are allowed solely on authentication (i.e. 
all authenticated users can do some things).

I'm sure I could have worked around #1, but #2 was a killer for this 
idea.  The idea would probably work if everything required a permission.

Instead, what I ended up doing is putting a isUserLocked(..) check in my 
custom filter.  I'd already extended FormAuthenticationFilter for other 
reasons, so in isAccessAllowed(...) I check to see if the account is 
locked.  If it has been locked, then I log the user out so they are no 
longer authenticated.

This achieves my goal, but has a few draw backs.
1) It is essentially polling the database.  User driven polling, but 
polling.
2) If the user goes through a different filter, that filter needs to be 
modified as well.

Given how well the framework for Shiro is designed, I still think I must 
be missing some clever way to get the subject associated with a session 
and force it to log out.  When an admin locks an account, I can get the 
locked user's session(s), but I couldn't find a way to affect the 
subject that they were using.

Thanks for your help.

Sincerely,
Stephen McCants

On 9/26/2013 6:36 PM, Jared Bunting wrote:
>
> How long is your cache timeout for permission lookups?  If it's 
> relatively short, you could modify your realm to return zero 
> permissions for a locked out user.  Then, they may remain logged in 
> but they have no permissions - and therefore can't do anything.
>
> On Sep 26, 2013 6:32 PM, "Stephen McCants" <stephen.mccants@hcs.us.com 
> <ma...@hcs.us.com>> wrote:
>
>     Hello All,
>         I'm working on a new problem and haven't found a good solution.
>         We have the ability to lock a user's account which prevents
>     them from logging in.  This is implemented in our custom Realm.
>      However, if a user is already logged in, they can continue to do
>     things until their session expires or they logout.
>         We'd like to be able to boot someone out immediately, but I
>     haven't been able to find a good way to do this.  My main approach
>     was to modify their session, but that seemed to have no effect on
>     their Subject in their ThreadContext.
>         Here are some of the things I tried doing to their session:
>
>             SessionDAO sdao = DAOUtils.getFactory().getSessionDAO();
>     // Get the custom session DAO
>             sdao.getActiveSessions();
>             for (Session s:sessions) {
>                     // Find the session based on the locked user's
>     principal
>                     s.stop();
>                     sdao.update(s);
>             }
>
>     Also tried:
>
>     s.setAttribute(org.apache.shiro.subject.support.DefaultSubjectContext.AUTHENTICATED_SESSION_KEY,
>     false);
>             sdao.update(s);
>
>     And:
>             sdao.delete(s);
>
>     I also tried building a new subject from the session and logging
>     it out:
>
>             Subject foreignSubject = new
>     Subject.Builder().session(s).buildSubject();
>             foreignSubject.logout();
>
>     I think the problem is the real Subject is cached in a ThreadLocal
>     and not accessible (unless the person locking the account is
>     locking their own account).  The cached Subject doesn't get
>     updated when the session has changed.
>         Does anyone have any recommendations or even a good solution
>     to this problem?  I'm sure I'm not the first to want to do this.
>         Thanks in advance!
>
>             Sincerely,
>                 Stephen McCants
>
>     -- 
>     Stephen McCants
>     Senior Software Engineer
>     Healthcare Control Systems
>     1-877-877-8795 x116 <tel:1-877-877-8795%20x116>
>


-- 
Stephen McCants
Senior Software Engineer
Healthcare Control Systems
1-877-877-8795 x116


Re: Forced Logout on User ID Locked

Posted by Jared Bunting <ja...@peachjean.com>.
How long is your cache timeout for permission lookups?  If it's relatively
short, you could modify your realm to return zero permissions for a locked
out user.  Then, they may remain logged in but they have no permissions -
and therefore can't do anything.
On Sep 26, 2013 6:32 PM, "Stephen McCants" <st...@hcs.us.com>
wrote:

> Hello All,
>     I'm working on a new problem and haven't found a good solution.
>     We have the ability to lock a user's account which prevents them from
> logging in.  This is implemented in our custom Realm.  However, if a user
> is already logged in, they can continue to do things until their session
> expires or they logout.
>     We'd like to be able to boot someone out immediately, but I haven't
> been able to find a good way to do this.  My main approach was to modify
> their session, but that seemed to have no effect on their Subject in their
> ThreadContext.
>     Here are some of the things I tried doing to their session:
>
>         SessionDAO sdao = DAOUtils.getFactory().**getSessionDAO(); // Get
> the custom session DAO
>         sdao.getActiveSessions();
>         for (Session s:sessions) {
>                 // Find the session based on the locked user's principal
>                 s.stop();
>                 sdao.update(s);
>         }
>
> Also tried:
>
> s.setAttribute(org.apache.**shiro.subject.support.**DefaultSubjectContext.
> **AUTHENTICATED_SESSION_KEY, false);
>         sdao.update(s);
>
> And:
>         sdao.delete(s);
>
> I also tried building a new subject from the session and logging it out:
>
>         Subject foreignSubject = new Subject.Builder().session(s).**
> buildSubject();
>         foreignSubject.logout();
>
> I think the problem is the real Subject is cached in a ThreadLocal and not
> accessible (unless the person locking the account is locking their own
> account).  The cached Subject doesn't get updated when the session has
> changed.
>     Does anyone have any recommendations or even a good solution to this
> problem?  I'm sure I'm not the first to want to do this.
>     Thanks in advance!
>
>         Sincerely,
>             Stephen McCants
>
> --
> Stephen McCants
> Senior Software Engineer
> Healthcare Control Systems
> 1-877-877-8795 x116
>
>