1. Apache Shiro中的permission是什么
Shiro 将 Permission 定义为代表某个明确行为或动作的语句。 它是应用程序中原始功能的声明,仅此而已。 权限是安全策略中最低级别的结构,它们仅明确定义应用程序可以做什么,而不会描述谁可以做这些动作。(和subject即认证主体无关)
2. permission体现在哪些地方
打开一个文件
访问
/user/list
路径下的网页打印文档
删除某个用户
定义“谁”(用户)被允许做“什么”(权限)是一种以某种方式为用户分配权限的运用,这始终由应用程序的数据模型完成,并且可能因应用程序而异。
例如,权限可以归入一个角色,并且该角色可以与一个或多个用户对象相关联。 或者一些应用程序可以有一个用户组,一个组可以分配一个角色,通过传递关联意味着该组中的所有用户都被隐式授予角色中的权限。
向用户授予权限的方式有多种变化——应用程序根据应用程序要求确定如何对此进行建模。
3. 通配符权限
上面的权限示例中,“打开文件”,“查看‘用户/列表’网页”等都是有效的权限声明。 然而,在计算上解释这些自然语言字符串并确定是否允许用户执行该行为将是非常困难的。因此,为了实现易于处理但仍然可读的权限语句,Shiro 提供了强大而直观的权限语法,我们称之为通配符权限。
3.1 简单应用
假设您想保护对公司打印机的访问,以便某些人可以打印到特定的打印机,而其他人可以查询当前队列中的作业。
一种极其简单的方法是授予用户“queryPrinter”权限。 然后您可以通过调用来检查用户是否具有 queryPrinter 权限:
1 | subject.isPermitted("queryPrinter") |
这等价于:
1 | subject.isPermitted( new WildcardPermission("queryPrinter") ) |
这还不够,简单权限字符串可能适用于简单的应用程序,但它需要您拥有“printPrinter”、“queryPrinter”、“managePrinter”等权限。您也可以使用通配符授予用户“*”权限(授予此权限) 构造其名称),这意味着它们拥有整个应用程序的所有权限。
但是使用这种方法,不能只说用户拥有“所有打印机权限”。 因此,通配符权限支持多级权限。
3.2 多个部件
通配符权限支持多个级别或部分的概念。 例如,您可以通过授予用户权限来重构前面的简单示例
1 | printer:query |
本示例中的冒号是一个特殊字符,用于分隔权限字符串中的下一部分。
在此示例中,第一部分是正在操作的域(打印机),第二部分是正在执行的操作(查询)。 上面的其他示例将更改为:
1 | printer:print |
可以使用的部件数量没有限制,因此就可以在您的应用程序中使用它的方式而言,这取决于您的想象力。
3.2.1 多个值
每个部分可以包含多个值。 因此,与其同时授予用户“printer:print”和“printer:query”权限,您还可以简单地授予他们一个权限:
1 | printer:print,query |
这使他们能够打印和查询打印机。 并且由于他们被授予了这两个操作,您可以检查用户是否有能力通过调用来查询打印机:
1 | subject.isPermitted("printer:query") |
这将返回 true。
3.2.2 全部的值
如果您想授予用户特定部分的所有值怎么办? 这样做比手动列出每个值更方便。 同样,基于通配符,我们可以做到这一点。 如果打印机域有 3 个可能的操作(查询、打印和管理),则:
1 | printer:query,print,manage |
可以简化为:
1 | printer:* |
然后,对“printer:XXX”的任何权限检查都将返回 true。 以这种方式使用通配符比显式列出操作更有效,因为如果稍后向应用程序添加新操作,则无需更新在该部分使用通配符的权限。
最后,还可以在通配符权限字符串的任何部分使用通配符标记。 例如,如果您想授予用户跨所有域(不仅仅是打印机)的“查看”操作,您可以授予以下权限:
1 | *:view |
然后对“foo:view”的任何权限检查都将返回true。