shiro框架权限验证逻辑

初次学习shiro是从iteye上的《跟我学shiro》,后来开始自己研究shiro的源码,发现《跟我学shiro》中对这个框架的权限对比讲的不够详细,所以把自己研究后对shiro的权限的理解写一下。

 

shiro框架中,权限对象的抽象接口为“org.apache.shiro.authz.Permission”。这个接口只有一个方法:implies,这个方法的输入输出与Object.equals方法很像,输入是一个Permission对象,输出则是boolean类型。含义也很明显:我这个权限对象与其它权限对象进行对比,如果验证通过,返回真,不通过,返回假。

 

在org.apache.shiro.realm.AuthorizingRealm类的子类中,需要实现protectedAuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals)方法,在这个方法中,将为用户设置拥有的权限信息。下面将举一个简单的例子。

 

 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollectionprincipals) {

         

       String username = (String) super.getAvailablePrincipal(principals);

 

       User user = userDao.findUserByUsername(username);

 

       SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

 

       info.addStringPermission("系统:用户菜单:新增,删除,修改");

 

       info.addStringPermission("系统:商品菜单:新增,删除,修改");

   

       info.addStringPermission("系统:商品菜单:新增,删除,修改");

   

       return info;

 

    }

 

而在用户权限需要验证时,调用subject.checkPermission("系统:商品菜单:新增")即可以进行用户的权限验证。

 

下面,就讲一下权限验证的判断逻辑。

 

一个用户会拥有多个权限,我们在下文中,称此用户拥有的这些权限为“用户权限集合”。

用户想要执行某操作的时候,系统总是用某一权限值与此用户的用户权限集合进行比对,以判断此用户有无此权限,则我们在下文中称此“某一权限值”为“操作权限值”。

 

 

无论是用户权限集合中的权限值与操作权限值,结构都是相同的。

 

下面重点介绍单一权限值的结构:

 

单一权限值的形式如下:

 

系统:用户菜单:新增,删除,修改

 

每一个shiro中的权限值都分为2层结构

 

第1层由“:”分隔

“系统”、“用户菜单”、“新增,删除,修改”三项分别为第一层的元素

第1层中的元素最少有一个,可以有无限多个

如“系统”这种权限值是合法的,“系统:菜单:用户菜单:新增操作:新增用户操作”这种权限值也是合法的。

在下文中,我们成第1层中的元素为“权限1级单位”。

 

第2层由“,”分隔

“新增”、“删除”,“修改”分别为第二层的元素。

其实“系统”、“用户菜单”也分别为第二层的元素

第2层中的元素最少有一个,可以有无限多个

如“查询”这种权限值是合法的,“新增,查询,修改,删除”这种权限值也是合法的。

在下文中,我们称第2层中的元素为“权限2级单位”。

 

权限1级单位之间有前后顺序,顺序不可以颠倒。

如“系统:菜单:用户菜单”和“系统:用户菜单:菜单”两个权限值不相等。

 

权限2级单位之间没有前后顺序,顺序可以颠倒。

如“新增,修改,删除,查询”和“查询,新增,删除,修改”两个子权限值是相等的。

 

权限1级单位集合在JAVA代码中的映射形式是List,权限2级单位集合在JAVA代码中的映射形式是Set,单个权限2级单位在JAVA代码中的映射形式是String。

 

两个权限进行比对的时候,系统会认为每个权限都至少有1个权限1级单位和1个权限2级单位。

 

我下面讲的文字中“权限比对是相等的”含义是“imply结果是true”,并不代表两个权限完全一样,也可能是一个权限完全包含另一个权限。

 

用户权限集合和某一操作权限进行比对的具体过程是:

 

用户权限集合中的权限与一个操作权限值对比的时候,如果任何1个用户权限与操作权限值对比为真,则整体对比结果为真。全部对比结果都为假,则整体对比结果才为假。

 

权限1级单位是有顺序的,两个权限相对比的时候,权限1级单位按顺序进行对比。对比结果只有两种:真或假。如果遇到真,则继续向后判断。如果遇到假,则直接返回“权限不符合”。

 

如果用户权限中只包含父权限,而操作权限值是父权限加子权限,并且两个权限的父权限级别比对全部为真,那么此权限比对结果为真。

如用户权限为“系统:菜单”,操作权限为“系统:菜单:用户菜单:测试,新增,修改,删除”,则此权限比对结果为真。

这可以理解为:我需要你有子权限才可以执行,而你不止有子权限,连父权限都有,我当然允许你执行。我需要你有三把钥匙中的1把才能打开锁,而你三把钥匙都有,当然能打开。

 

如果操作权限中只包含父权限,而用户权限值是父权限加子权限,并且两个权限的父权限级别比对全部为真,那么此权限比对结果为假。

如操作权限为“系统:菜单”,用户权限为“系统:菜单:用户菜单:测试,新增,修改,删除”,则此权限比对结果为假。

这可以理解为:我需要你有父权限才可以执行,而你只有子权限,我当然不允许你执行。我需要你同时把三把钥匙插入1把锁,才能打开锁,而你只有1把钥匙,当然打不开。

 

权限2级单位是没有顺序的,两个权限2级单位进行对比的时候,是看用户权限中的所有2级单位内容,是否包含了操作权限中的所有2级单位内容。如果包含了操作权限中的所有2级单位内容,则对比结果为真,如果至少1项操作权限中的2级单位内容,在用户权限中没有,则对比结果为假。

就是判断操作权限中的所有2级单位内容集合,是否是用户权限中所有2级单位内容集合的子集,如果是子集,则对比结果为真,否则为假。

 

“*”可以代替某个一级权限下的所有的二级权限集合。

例如:“系统:菜单:用户菜单:*”与“系统:菜单:用户菜单:测试,新增,修改,删除”两个权限值比对是相等的。

“*”后面还可以带一级权限和二级权限,如“系统:菜单:用户菜单:*:删除ID为112的记录”在结构上是合法的。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值