Reputation: 6504
I'm using Apache Shiro (v1.2.3) and I have username/password authentication setup correctly and it's working (I'm storing the password hashes and salts in a remote database). I'm now trying to setup permissions using roles. I have a single realm that extends AuthorizingRealm
e.g.
public class MyRealm extends AuthorizingRealm {
@Override
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken token) throws AuthenticationException {
// no problems here...
}
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principles) {
Set<String> roles = // get the roles for this user from the DB
LOG.info("Found roles => " + roles.toString());
return new SimpleAuthorizationInfo(roles);
}
}
My shiro.ini
looks like this:
[main]
myRealm = ie.enki.closing.users.MyRealmcredentialsMatcher = org.apache.shiro.authc.credential.Sha256CredentialsMatcher
credentialsMatcher.storedCredentialsHexEncoded = false
credentialsMatcher.hashIterations = 1024myRealm.credentialsMatcher = $credentialsMatcher
cacheManager = org.ehcache.integrations.shiro.EhcacheShiroManager
securityManager.cacheManager = $cacheManager[roles]
admin = *
staff = resource_1:action_1
The relevant startup logging reports that ehcache is being setup correctly but before it does, it also mentions this:
[main] INFO org.apache.shiro.realm.text.IniRealm - IniRealm defined, but there is no [users] section defined. This realm will not be populated with any users and it is assumed that they will be populated programatically. Users must be defined for this Realm instance to be useful.
[main] INFO org.apache.shiro.realm.AuthorizingRealm - No cache or cacheManager properties have been set. Authorization cache cannot be obtained.
...
some ehcache setup logging...
In my testing, currentUser.isPermitted("resource_1:action_1")
returns false
even though my logging says that I do have the admin
role (I've tried it with the staff
role too).
The shiro docs talk about setting up a [users] section in the shiro.ini
and assigning roles to users like:
[users]
some_user = password, role1, role2
...but I don't want to define users and their passwords in the ini file. That's what my database is for. Have I misunderstood something in the configuration?
After going through the docs again, it seems that the [roles] section is only applicable if you're using the [users] section to define a small number of static users. If that's true, how do you associate roles with permissions for users defined in a database. The docs that might reveal this info are incomplete.
Upvotes: 0
Views: 2446
Reputation: 1140
When you're not using IniRealm
, you don't directly map Roles -> Permissions. You have to tell Shiro what permissions a User has with SimpleAuthorizationInfo
's addStringPermissions or addObjectPermissions and if you're using roles to assign groups of permissions manually retrieve those.
There are multiple ways to do this depending on your app. Without knowing how complex your application is, it's difficult to recommend an approach. For maximum flexibility, you can create 3 database tables: USER_PERMISSIONS
, ROLE_PERMISSIONS
, and USER_ROLES
.
If you're only doing permission checks, I'd recommend doGetAuthorizationInfo
only retrieve the permissions assigned to a user. Roles would only be used on the front-end to assist in assigning groups of permissions to certain users. This is the Explicit Role recommended by Shiro in Roles.
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principles) {
Set<String> permissions = // get the permissions for this user from the DB
SimpleAuthorizationInfo simpleAuth = new SimpleAuthorizationInfo();
simpleAuth.addStringPermissions(permissions);
return simpleAuth;
}
P.S. I would remove the [roles]
section and explicitly define your realm to Shiro. Implicit Assignment is not recommended. To do this, add the following line to your configuration after removing [roles]
.
securityManager.realms = $myRealm
Upvotes: 2