shiro的RequiresPermissions注解用法

RequiresPermissions的作用

RequiresPermissions是shiro提供的一个注解类。主要是用作权限校验的一种方式。

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RequiresPermissions {
    /**
     * The permission string which will be passed to {@link org.apache.shiro.subject.Subject#isPermitted(String)}
     * to determine if the user is allowed to invoke the code protected by this annotation.
     */
    String[] value();    
    /**
     * The logical operation for the permission checks in case multiple roles are specified. AND is the default
     * @since 1.1.0
     */
    Logical logical() default Logical.AND; 
}

一般情况下,注解类作用在需要拦截的方法上。
从value的注释上可以看到,注解上的第一个参数的值会传到Subject的isPermitted方法去。所以原理都是通过Subject的isPermitted去校验权限。

RequiresPermissions的value格式

  • 简单形式
    value只是一个普通的字符串比如:@RequiresPermissions(“dosomething”)
  • 多层级形式
    用冒号隔开两个字符串,比如:@RequiresPermissions(“dosomething:view,edit”)
    冒号隔开的第一个字符串一般是操作的领域对象,而第二个字符串一般是操作的类型。
  • 实例级访问控制
    用冒号隔开多个字符串,比如:@RequiresPermissions(“dosomething:view,edit:213”)冒号隔开的第三个字符串内容一般是一个操作对象的id,来控制具体的对象实例是否有权限来调用方法。

这个格式应该只是一种规范标准,不一定非要严格执行才能达到效果。

# WildcardPermissionResolver类中
    public Permission resolvePermission(String permissionString) {
        return new WildcardPermission(permissionString);
    }
#AuthorizingRealm类中的两个方法:
根据字符串resolve成的一个Permission
    public boolean isPermitted(PrincipalCollection principals, String permission) {
        Permission p = getPermissionResolver().resolvePermission(permission);//实现在WildcardPermissionResolver类中
        return isPermitted(principals, p);
    }

在AuthorizingRealm类中的权限比较实现。而其中的permission就是上面生成的,而AuthorizationInfo的内容一般都是从数据库等等地方查询出权限列表寄放到info里。
//visibility changed from private to protected per SHIRO-332
    protected boolean isPermitted(Permission permission, AuthorizationInfo info) {
        Collection perms = getPermissions(info);
        if (perms != null && !perms.isEmpty()) {
            for (Permission perm : perms) {
                if (perm.implies(permission)) {
                    return true;
                }
            }
        }
        return false;
    }

public boolean implies(Permission p) {
        // By default only supports comparisons with other WildcardPermissions
        if (!(p instanceof WildcardPermission)) {
            return false;
        }

        WildcardPermission wp = (WildcardPermission) p;

        List> otherParts = wp.getParts();

        int i = 0;
        for (Set otherPart : otherParts) {
            // If this permission has less parts than the other permission, everything after the number of parts contained
            // in this permission is automatically implied, so return true
            if (getParts().size() - 1 < i) {
                return true;
            } else {
                Set part = getParts().get(i);
                if (!part.contains(WILDCARD_TOKEN) && !part.containsAll(otherPart)) {
                    return false;
                }
                i++;
            }
        }

        // If this permission has more parts than the other parts, only imply it if all of the other parts are wildcards
        for (; i < getParts().size(); i++) {
            Set part = getParts().get(i);
            if (!part.contains(WILDCARD_TOKEN)) {
                return false;
            }
        }

        return true;
    }

所以value只要和存储在数据库里面的权限信息段一致应该就可以。

你可能感兴趣的:(开发)