4

I have to deal with an application which is secured by apache shiro. I'm quite new to this framework. As far as I can see, I can check single rights via subject.isPermitted(), e.g.

Subject subject = SecurityUtils.getSubject();
[...]
subject.isPermitted("$RightString");

For logging purposes I need the complete list of user rights as a String. And I do not want to iterate over the list of rights and check everytime, whether subject.isPermitted() is true

Is there any shortcut to this problem?

Edit:

Further Information:

  • Application is a Spring 4 Application
  • realm is defined in in application context as a bean

     <bean id="PRODUCTNAMERealm" class="de.PATHFROMPRODUCT_PRODUCTNAMEJdbcRealm">
         <property name="dataSource" ref="dataSource"/>
         <property name="schema" value="${PRODUCTNAME.schema}"/>
     </bean>
    

    so i could inject it if needed.

Thomas Junk
  • 5,588
  • 2
  • 30
  • 43

3 Answers3

4

I believe there is no out of the box way to do this, be we worked around this by registering the user permissions on the session. We are using a custom realm implementation and our permissions are stored in the database.

In our custom realm class:

@Override
public AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
    SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
    Set<String> permissionsSet = //logic to get the permissions here

    info.addStringPermissions(permissionsSet);

    SecurityUtils.getSubject().getSession().setAttribute("permissions", permissionsSet);
    return info;
}

Now retrieving the permissions is just a matter of calling:

SecurityUtils.getSubject().getSession().getAttribute("permissions");

Another way would be to inject your custom realm where you need the info and have the bean make getAuthorizationInfo public.

@Override
public AuthorizationInfo getAuthorizationInfo(PrincipalCollection principals) {
    return super.getAuthorizationInfo(principals);
}

....

yourRealm.getAuthorizationInfo(SecurityUtils.getSubject().getPrincipals()).getStringPermissions();
Wouter
  • 3,976
  • 2
  • 31
  • 50
  • If I'm understanding you right: I have to get the source of the implementation of the custom realm class (in my case the extension of JdbcRealm) and I will have two chioces - if your code is right: a) put the permissions into the session and later retrieve it from there and b) what your code suggests: just get the AuthorizationInfo. There should be a getter. Unfortunately I have to wait till Monday. But I'll check that out and let you know. – Thomas Junk Aug 29 '14 at 20:41
  • Yes. Getting hold of the AuthorizationInfo would also work as it has a getStringPermission method giving you a set of all perms. We don't use that way however in our project. I don't think there is an easy way to get it as this object is only used in realms and it is never exposed directly. – Wouter Aug 30 '14 at 06:12
  • I now see you are using spring so you can also inject the jdbc realm and indeed get the AuthorizationInfo object, adjusted my answer for this. – Wouter Aug 30 '14 at 06:18
  • I accept your answer, because it should work. But as I realized, my root problem has shifted in an unexpected direction, so I do not need to resolve the user rigths.Tank you very much! – Thomas Junk Sep 01 '14 at 07:54
1

In my opinion Shiro is related to only security, authority, etc of current user not to the whole user base. You can use your standard SQL queries to retrieve users permissions.

Muhammad Suleman
  • 2,892
  • 2
  • 25
  • 33
  • We are storing indeed the user-rights in a db. So if I'm interested in a users's rights, I could query the DB. But what I've not mentioned is the context or the purpose for what I am doing this. Currently we have problems in a Shiro/Cluster-scenario, where it seems, that Shirosession "forgets" users/rights. And to debug that case, I wanted to trace in certain cases, what user is logged in, and what rights does Shiro associate with this special user. Somewhere is a hole in our setup and at present I do not know where. – Thomas Junk Sep 01 '14 at 14:38
1

you may override function getAuthorizationInfo in own AuthorizingRealm implementation

public class LoginPasswordRealm extends AuthorizingRealm {
    @Override
    public AuthorizationInfo getAuthorizationInfo(PrincipalCollection principals){
        return super.getAuthorizationInfo(principals);
    }
}

and then user it:

Subject currentUser = SecurityUtils.getSubject();
LoginPasswordRealm realm = (LoginPasswordRealm)securityManager.getRealms().iterator().next();
AuthorizationInfo authorizationInfo = realm.getAuthorizationInfo(currentUser.getPrincipals());
authorizationInfo.getStringPermissions().forEach(System.out::println);
pwipo
  • 463
  • 3
  • 7