You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@shiro.apache.org by Tauren Mills <ta...@groovee.com> on 2013/05/06 02:57:04 UTC

Clearing cached permissions for a different user

How do I clear the permission cache for a specific user when an
administrative user updates properties that affect that user's permissions?

I've been doing this when I want to update the current user's permissions:
realm.clearCachedAuthorizationInfo(SecurityUtils.getSubject().getPrincipals());

But how can I access the permissions cache of another user? Note that this
user might be currently active, but they might not as well.

I'm assuming I need to create a SimplePrincipalCollection, but what's the
best way to do that and where is the best location for that code? I believe
I need access to the realm name and the user id to do this. I'm thinking of
adding a method to my realm:

    public void clearCachedAuthorizationInfo(User user) {
        Long id = User.getId();
        String realmName = this.getName();
        SimplePrincipalCollection spc = // do something with id and
realmName
     this.clearCachedAuthorizationInfo(spc);
    }

Thanks,
Tauren

Re: Clearing cached permissions for a different user

Posted by Tauren Mills <ta...@tauren.com>.
Les,

Thanks, this worked perfectly!  I overrode getAuthorizationCacheKey() as
you suggested so that the cache key is only based on the primary principal.
Note that I didn't try it without overriding, so I'm not sure if it would
have worked that way. My app is only using one principal.

For my purpose, having this be Shiro's default would work well, but I'm not
sure if I'm the best person to advise you to make this change to Shiro. I'm
not as familiar with the impact the change would make on others who use
more than one principal. I'll leave it up to you to decide if you want to
introduce this.

Tauren




On Mon, May 6, 2013 at 10:02 AM, Les Hazlewood <lh...@apache.org>wrote:

> Hi Tauren,
>
> You can create a SimplePrincipalCollection manually, but with Shiro's
> default clearing behavior, the manually constructed instance must
> equal the one created by your Realm during authentication (in the
> AuthenticationInfo).
>
> For example:
>
> SimplePrincipalCollection spc = new SimplePrincipalCollection(id,
> realmName);
>
> //this should be true:
> spc.equals(authenticationInfoReturnedFromMyRealm.getPrincipals());
>
> Depending on the cache implementation,
>
> spc.hashCode().equals(authenticationInfoReturnedFromMyRealm.getPrincipals().hashCode())
> might have to be true as well.
>
> This is because the AuthorizingRealm's clearCachedAuthorizationInfo
> method, by default, uses the PrincipalCollection as the cache key,
> i.e. cache.remove(principalCollection).
>
> But you can change this if it doesn't meet your needs.  Perhaps you
> want the cache key to only be the 'primary principal' - which looks
> like your user id in your case - and not the entire
> PrincipalCollection.  You can override the
> getAuthorizationCacheKey(PrincipalCollection) method:
>
> @Override
> protected Object getAuthorizationCacheKey(PrincipalCollection pc) {
>     return principals.getPrimaryPrincipal();
> }
>
> Note that this is different than getAuthenticationCacheKey (used
> during authentication caching only) - but if used, it can have the
> same implementation as getAuthorizationCacheKey as well.
>
> Perhaps Shiro's default implementation should just rely on the primary
> principal as the cache key by default.  I didn't write it that way in
> the beginning because the PC represents the entire identity of the
> current Subject, which may or may not be more than one principal.  But
> for caching, maybe it's best just to use the primary.  Please open a
> Jira issue if you agree :)
>
> HTH,
>
> --
> Les Hazlewood | @lhazlewood
> CTO, Stormpath | http://stormpath.com | @goStormpath | 888.391.5282
>
> On Sun, May 5, 2013 at 5:57 PM, Tauren Mills <ta...@groovee.com> wrote:
> > How do I clear the permission cache for a specific user when an
> > administrative user updates properties that affect that user's
> permissions?
> >
> > I've been doing this when I want to update the current user's
> permissions:
> >
> realm.clearCachedAuthorizationInfo(SecurityUtils.getSubject().getPrincipals());
> >
> > But how can I access the permissions cache of another user? Note that
> this
> > user might be currently active, but they might not as well.
> >
> > I'm assuming I need to create a SimplePrincipalCollection, but what's the
> > best way to do that and where is the best location for that code? I
> believe
> > I need access to the realm name and the user id to do this. I'm thinking
> of
> > adding a method to my realm:
> >
> >     public void clearCachedAuthorizationInfo(User user) {
> >         Long id = User.getId();
> >         String realmName = this.getName();
> >         SimplePrincipalCollection spc = // do something with id and
> > realmName
> >      this.clearCachedAuthorizationInfo(spc);
> >     }
> >
> > Thanks,
> > Tauren
> >
>

Re: Clearing cached permissions for a different user

Posted by Les Hazlewood <lh...@apache.org>.
Hi Tauren,

You can create a SimplePrincipalCollection manually, but with Shiro's
default clearing behavior, the manually constructed instance must
equal the one created by your Realm during authentication (in the
AuthenticationInfo).

For example:

SimplePrincipalCollection spc = new SimplePrincipalCollection(id, realmName);

//this should be true:
spc.equals(authenticationInfoReturnedFromMyRealm.getPrincipals());

Depending on the cache implementation,
spc.hashCode().equals(authenticationInfoReturnedFromMyRealm.getPrincipals().hashCode())
might have to be true as well.

This is because the AuthorizingRealm's clearCachedAuthorizationInfo
method, by default, uses the PrincipalCollection as the cache key,
i.e. cache.remove(principalCollection).

But you can change this if it doesn't meet your needs.  Perhaps you
want the cache key to only be the 'primary principal' - which looks
like your user id in your case - and not the entire
PrincipalCollection.  You can override the
getAuthorizationCacheKey(PrincipalCollection) method:

@Override
protected Object getAuthorizationCacheKey(PrincipalCollection pc) {
    return principals.getPrimaryPrincipal();
}

Note that this is different than getAuthenticationCacheKey (used
during authentication caching only) - but if used, it can have the
same implementation as getAuthorizationCacheKey as well.

Perhaps Shiro's default implementation should just rely on the primary
principal as the cache key by default.  I didn't write it that way in
the beginning because the PC represents the entire identity of the
current Subject, which may or may not be more than one principal.  But
for caching, maybe it's best just to use the primary.  Please open a
Jira issue if you agree :)

HTH,

--
Les Hazlewood | @lhazlewood
CTO, Stormpath | http://stormpath.com | @goStormpath | 888.391.5282

On Sun, May 5, 2013 at 5:57 PM, Tauren Mills <ta...@groovee.com> wrote:
> How do I clear the permission cache for a specific user when an
> administrative user updates properties that affect that user's permissions?
>
> I've been doing this when I want to update the current user's permissions:
> realm.clearCachedAuthorizationInfo(SecurityUtils.getSubject().getPrincipals());
>
> But how can I access the permissions cache of another user? Note that this
> user might be currently active, but they might not as well.
>
> I'm assuming I need to create a SimplePrincipalCollection, but what's the
> best way to do that and where is the best location for that code? I believe
> I need access to the realm name and the user id to do this. I'm thinking of
> adding a method to my realm:
>
>     public void clearCachedAuthorizationInfo(User user) {
>         Long id = User.getId();
>         String realmName = this.getName();
>         SimplePrincipalCollection spc = // do something with id and
> realmName
>      this.clearCachedAuthorizationInfo(spc);
>     }
>
> Thanks,
> Tauren
>