Apache Shiro 角色和权限不起作用

Apache Shiro roles and permissions not working

我正在使用 Apache Shiro (v1.2.3),并且我有 username/password 身份验证设置正确并且它正在工作(我将密码哈希和盐存储在远程数据库中)。我现在正在尝试使用角色设置权限。我有一个扩展 AuthorizingRealm 的单一领域,例如

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);
    }

}

我的 shiro.ini 看起来像这样:

[main]
myRealm = ie.enki.closing.users.MyRealm

credentialsMatcher = org.apache.shiro.authc.credential.Sha256CredentialsMatcher
credentialsMatcher.storedCredentialsHexEncoded = false
credentialsMatcher.hashIterations = 1024

myRealm.credentialsMatcher = $credentialsMatcher

cacheManager = org.ehcache.integrations.shiro.EhcacheShiroManager
securityManager.cacheManager = $cacheManager

[roles]
admin = *
staff = resource_1:action_1

相关的启动日志报告说 ehcache 正在正确设置,但在此之前,它还提到了这一点:

[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...

在我的测试中,currentUser.isPermitted("resource_1:action_1") returns false 尽管我的日志显示我确实拥有 admin 角色(我已经用 staff也有作用)。

shiro 文档讨论了在 shiro.ini 中设置 [users] 部分并为用户分配角色,例如:

[users]
some_user = password, role1, role2

...但我不想在 ini 文件中定义用户及其密码。这就是我的数据库的用途。我对配置有什么误解吗?

再次查看文档后,似乎 [roles] 部分仅适用于使用 [users] 部分定义少量静态用户的情况。如果是这样,您如何将角色与数据库中定义的用户的权限相关联。 docs that might reveal this info 不完整。

当您不使用 IniRealm 时,您不会直接映射角色 -> 权限。您必须告诉 Shiro 用户对 SimpleAuthorizationInfoaddStringPermissions or addObjectPermissions 有什么权限,如果您使用角色分配权限组,请手动检索这些权限。

有多种方法可以执行此操作,具体取决于您的应用。在不知道您的应用程序有多复杂的情况下,很难推荐一种方法。为了获得最大的灵活性,您可以创建 3 个数据库表:USER_PERMISSIONSROLE_PERMISSIONSUSER_ROLES.

如果您只进行权限检查,我建议 doGetAuthorizationInfo 只检索分配给用户的权限。角色只会在前端使用,以协助为特定用户分配权限组。这是 Shiro 在 Roles.

中推荐的 Explicit Role
@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。我会删除 [roles] 部分并将您的领域明确定义给 Shiro。 Implicit Assignment 不推荐。为此,请在删除 [roles].

后将以下行添加到您的配置中
securityManager.realms = $myRealm