Shiro User Manual-Authorization-Permissions

1. Wildcard Permissions
为了易读和简化处理,Shiro提供了强大且直观的权限语法,即WildcardPermission(通配符权限)。

1.1 Simple Usage
假设你想保护公司打印机的使用,一些人可以使用打印机,一些人只能查看打印机服务器队列中的任务。最简单的方式就是定义一个queryPrinter权限,然后检查用户是否具有这个权限:

subject.isPermitted("queryPrinter")

这段代码等同于:

subject.isPermitted( new WildcardPermission("queryPrinter") )

这种基于字符串式权限的使用,只适用于简单的应用。你可以赋予用户*权限,意味着用户拥有应用中所有的权限。

A. Multiple Parts
WildcardPermission支持多级配置。对于赋予用户"printer:print"和"printer:query"权限,可以简化为:

printer:print,query

然后,可以这样执行验证:

subject.isPermitted("printer:query")

它将返回true。
B. All Values
如果想赋予用户某一模块全部的权限,比如,将打印机的3项操作query, print, 和manage权限都赋予用户,可以这样配置:

printer:query,print,manage

也可以这么配置:

printer:*

那么,对于"printer:XXX"的所有检查,都将返回true。使用这种方式,在新增一个操作时,你就无需再更改权限配置了。可以在任何地方使用通配符,比如,赋予用户所有域的view权限:

*:view

那么,对"foo:view"的检查将返回true。

1.2 Instance-Level Access Control
另一个方式是使用实例级访问控制列表。需要配置三部分内容:第一部分代表域级,第二部分代表行为级,第三部分代表实例级。

printer:query:lp7200
printer:print:epsoncolor

第一个配置定义了ID为lp7200实例对printer(打印机)具有query(查询)权限。
第二个配置定义了ID为epsoncolor实例对printer具有print(打印)权限。
然后执行检查权限:

if ( SecurityUtils.getSubject().isPermitted("printer:query:lp7200") {
// Return the current jobs on printer lp7200
}

这种方式有利于体现用户的权限。但是,如果为所有的打印机定义实例,不利于扩展,特别是在新增一台打印机的时候。你可以使用通配符替代:

printer:print:*

通配符有利于扩展,因为它也包含了新增打印机。也可以这样配置,拥有所有打印机的所有权限:

printer:*:*

或者某台打印机的所有操作权限:

printer:*:lp7200

或某台打印机的某些操作权限:

printer:query,print:lp7200

通配符"*"和",",可以在三部分内容的任何一部分进行使用。

A. Missing Parts
最后需要注意的是,对于这三部分的配置,缺失的部分表示这个用户拥有所有这部分对应的值。

printer:print

等同于:

printer:print:*



printer

等同于

printer:*:*

但是,缺失的部分只能从后开始:

printer:lp7200

不等同于

printer:*:lp7200


2. Checking Permissions
使用通配符构建的权限分配,具有方便性,可伸缩性。对于想使用实例为lp7200的打印机打印文档,需要这样检查:

if ( SecurityUtils.getSubject().isPermitted("printer:print:lp7200") ) {
//print the document to the lp7200 printer
}

这种检查直观的反映了用户的操作。而以下这种方式就不那么直观了:

if ( SecurityUtils.getSubject().isPermitted("printer:print") ) {
//print the document
}

为什么?因为第二个例子里,你必须有所有打印机的打印权限才行("printer:print"等同于"printer:print:*")。假设当前的用户不具有所有打印机的打印权限,而只具有lp7200和epsoncolor两台打印机的权限,那么在第二个例子中,就不允许其执行在lp7200和epsoncolor上的打印操作了,这是错误的。 实践中,最好指定完整的字符权限。

3. Implication, not Equality
为什么运行时权限检查要尽可能详细,而权限分配时可以简化呢?因为权限检查是依据隐式的业务逻辑,而不是简单的相等比较。就是说,如果用户被指定"user:*"权限,用户可以执行"user:view"操作。字符串"user:*"不等于"user:view",但是前者隐式的具有后者的操作。为了支持这种隐式的规则,所有权限都被转义为org.apache.shiro.authz.Permission接口,因此,隐式的业务逻辑可以在运行时执行。这篇文档中使用的通配符都被转换为了org.apache.shiro.authz.permission.WildcardPermission实例。
还有更多通配符权限的例子:

user:*

隐式表示其具有删除用户的权限:

user:delete

同样:

user:*:12345

隐式表示其具有更新用户ID 12345的权限:

user:update:12345

还有:

printer

隐式表示其具有所有打印机打印的权限。

printer:print


4. Performance Considerations
虽然WildcardPermission可以解决80-90%的用例,但是它并不是解决大量权限存储和验证最好的方案。
Shiro支持CacheManage,将用户,角色,权限缓存起来,然后执行验证,将大大提高验证效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值