Gareth,


I think a method for retrieving an authenticated Subject's permissions is 
probably not out of place in Shiro's API. There are definitely going to be 
cases where it's easier/faster/more efficient to check the Subject's 
permissions against a set of resources than to check the resources against 
their permissions. How exactly such a thing might be implemented is probably 
worthy of broader discussion. If I were to add such a feature, I'd probably 
want both a simple getter (getPermissions()) as well as something that 
functioned more like a callback (doWithPermissions(SomeCallback)) that would 
iterate over the Subject's permissions and call my callback with each.


I think, though, to some extent, there is a belief that Shiro itself may not 
need such methods, since it provides read-only access to a user/permission 
model. Allow me to explain. With the current Shiro design, the expectation is 
that you have built a Realm somewhere--those permissions must be loaded 
somehow, and that's code Shiro doesn't include. In the system I'm currently 
working on, for example, we have a ManagedDirectoryRealm. That Realm is 
created/wired using Spring, in our case, but it could as easily be 
created/wired using another DI framework, or Shiro's own INI config support. In 
doGetAuthenticationInfo() on our Realm implementation, we rely on an AccountDao 
instance which has been wired in to retrieve an Account by its e-mail address 
or username. That returned Account instance, in our system, has a 
getPermissions() method on it. The primary principal on the SimpleAccount 
returned is the primary key ID of the Account instance in our database. Because 
of these two facts, we can do something like the following:


public interface SecurityManager {

    @RequiresAuthentication

    long getCurrentPrincipal();

}

 

public class DefaultSecurityManager implements SecurityService {

    @Override

    public long getCurrentPrincipal() {

        return (Long) SecurityUtils.getSubject().getPrincipal();

    }

}

 

public interface AccountManager {

    @RequiresAuthentication

    Account getCurrentAccount();

}

 

public class DefaultAccountManager implements AccountManager {

    @Autowired

    private AccountDao accountDao;

    @Autowired

    private myexample.SecurityManager securityManager;

 

    public Account getCurrentAccount() {

        return accountDao.read(securityManager.getCurrentPrincipal());

    }

}


This way, anything in our system which needs the Account of the logged-in user 
in the executing context can get it. This is necessary because an Account has 
many fields for things like name, e-mail address, username, etc., and some 
parts of our system need those details. In your case, with something like this, 
you would be able to get the current Account and get its permissions.


The biggest shortcoming of this approach is that you won't really have access 
to a fully resolved set of Permissions (in the Shiro sense). If your version of 
an "Account" relies on groups and other things to define its overall set of 
permissions, this approach won't really help you as much. That's a case where 
adding the ability to Shiro to retrieve the fully-resolved set of Permissions 
for a Subject would be a very nice feature. It's one our own system is likely 
to need, so we'd likely be very interested in collaborating with you on a 
solution, if you wanted to participate in the process.


My suggestion would be to open an issue in Shiro's JIRA requesting the 
getPermissions() method you're looking for, and then post about the issue on 
Shiro's developers list (as opposed to its user list). I'm certain Les and 
Kalle and the other committers (I'm not one, but I've been following this list 
for a long time now) will have excellent ideas and feedback, and I know they're 
always willing to accept a well-though-out patch.


Hope this helps,

Bryan Turner

Katasoft, Inc


P.S. As an aside, if you cast the SecurityManager instance you get from 
SecurityUtils to either DefaultSecurityManager or RealmSecurityManager (which 
DefaultSecurityManager extends), you can call getRealms(). In your system as 
you've described it, the returned collection should have exactly 1 Realm 
instance in it, which will be your Realm implementation. This goes below the 
interfaces, unfortunately, but for the moment, until Shiro adds the 
getPermissions() method you need, this should let you use 
goGetAuthorizationInfo() to get a Subject's roles and permissions for yourself.



> Date: Sat, 30 Jul 2011 08:43:45 -0700
> From: [email protected]
> To: [email protected]
> Subject: Re: Retrieving The List Of Permissions (Or Roles) For A User
> 
> Hello Phil,
> 
> Thank you for responding!
> 
> That is true. If I could get the Realm then I could get access to the
> AuthorizationInfo (which would give me access to the Permissions and Roles).
> 
> How can the webapp get the realm though? In a web app, from SecurityUtils I
> have access to a SecurityManager or a Subject, neither of which give me
> access to the Realm.
> 
> If I take a look at Spring Security (I am trying hard to avoid using Spring
> Security as it forces you to bring in the whole Spring framework -> in an
> OSGi environment there are even more dependencies), in a webapp environment,
> I can cast the User Principal from the HttpServletRequest to interface
> Authentication, then I can go call "getAuthorities" which will allow me to
> get the list of GrantedAuthorities (which can be a list of roles or
> permissions).
> 
> Perhaps if subject is authenticated, Subject could have a method to return a
> list of the authorizing realms? Would that make sense?
> 
> thanks,
> Gareth
> 
> 
> 
> 
> 
> --
> View this message in context: 
> http://shiro-user.582556.n2.nabble.com/Retrieving-The-List-Of-Permissions-Or-Roles-For-A-User-tp6634613p6636404.html
> Sent from the Shiro User mailing list archive at Nabble.com.                  
>                   

Reply via email to