优先级模型,所谓优先级,是指按一定的顺序加载策略。
优先级高的策略先加载,先加载的策略具有较高的优先级。
PHP-Casbin 目前支持三种模式:隐式优先顺序加载策略、显示优先顺序加载策略、基于角色和用户的层级关系加载策略。
优先级模式的配置在model.conf
中的policy_effect
中配置。
隐式优先顺序加载策略
隐式优先级模型配置在官方仓库的 examples 目录下 priority_model.conf
文件中有示例,对应的策略文件为priority_policy.csv
。具体的 model 配置请看下面的解释。
[request_definition]
r = sub, obj, act
[policy_definition]
p = sub, obj, act, eft
[role_definition]
g = _, _
[policy_effect]
e = priority(p.eft) || deny
[matchers]
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act
可以看到policy_effect
部分的配置为:e = priority(p.eft) || deny
,在策略定义policy_definition
部分最后一个参数有个eft
决定参数,意思是在所有命中的策略中,策略的eft(p.eft
)参数的值如果为明确结果(allow 或 deny)就作为决策结果,否则就以拒绝(deny)为决策结果。p.eft
有三种取值:allow
、deny
、indeterminate
。
显示优先顺序加载策
参考官方文档Load Policy with Explicit Priority。
Currently, explicit priority only supports AddPolicy & AddPolicies. If UpdatePolicy has been called, you shouldn't change the priority attribute.
文档中有这么一句话,就是目前只支持添加策略和批量添加策略。如果是修改策略则不能修改策略的优先级。
配置在官方仓库的 examples 目录下 priority_model_explicit.conf
文件中有示例,对应的策略文件为priority_policy_explicit.csv
。
[request_definition]
r = sub, obj, act
[policy_definition]
p = priority, sub, obj, act, eft
[role_definition]
g = _, _
[policy_effect]
e = priority(p.eft) || deny
[matchers]
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act
这个配置相比隐式优先顺序加载策略
,只是在policy_definition
中加了一个priority
字段。就是在策略中用一个数值字段来代表优先级。看一下它的策略:
p, 10, data1_deny_group, data1, read, deny
p, 10, data1_deny_group, data1, write, deny
p, 10, data2_allow_group, data2, read, allow
p, 10, data2_allow_group, data2, write, allow
p, 1, alice, data1, write, allow
p, 1, alice, data1, read, allow
p, 1, bob, data2, read, deny
g, bob, data2_allow_group
g, alice, data1_deny_group
下面是验证示例:
alice, data1, write --> true // because `p, 1, alice, data1, write, allow` has the highest priority
bob, data2, read --> false
bob, data2, write --> true // because bob has the role of `data2_allow_group` which has the right to write data2, and there's no deny policy with higher priority
可以看出,优先级的值越小则优先级越高,即策略的排序是根据priority
字段从小到大升序。所以如果要指定策略的优先级只需要设置priority
字段的数值即可。
基于角色和用户的层级关系加载策略
顾名思义,用户和角色、角色和角色都有可能有一个继承关系,甚至是多层级关系,那么这些关系会形成一个树形
的层级,根据这个层级关系来加载策略,从而实现策略的优先级。
subject_priority_model.conf
配置如下:
[request_definition]
r = sub, obj, act
[policy_definition]
p = sub, obj, act, eft
[role_definition]
g = _, _
[policy_effect]
e = subjectPriority(p.eft) || deny
[matchers]
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act
在policy_effect
的配置为:e = subjectPriority(p.eft) || deny
,其中subjectPriority
意思就是根据主体(sub)来决定优先级。
subject_priority_policy.csv
如下:
p, root, data1, read, deny
p, admin, data1, read, deny
p, editor, data1, read, deny
p, subscriber, data1, read, deny
p, jane, data1, read, allow
p, alice, data1, read, allow
g, admin, root
g, editor, admin
g, subscriber, admin
g, jane, editor
g, alice, subscriber
下面是验证结果:
jane, data1, read --> true // because jane is at the bottom, her priority is higher than that of editor, admin, and root
alice, data1, read --> true
虽然jane
所属的角色editor
对data1
的read
是拒绝的(deny
),并且位置靠前,但jane
本身有一条对data1
的read
的允许allow
策略,即便位置靠后,jane
对 data1
的 read
仍然为 allow
。因为jane
位于层级的最底层,具有较高的优先级。
角色的层级关系像这样:
role: root
└─ role: admin
├─ role editor
│ └─ user: jane
│
└─ role: subscriber
└─ user: alice
那么优先级最终是这样的:
role: root # auto priority: 30
└─ role: admin # auto priority: 20
├─ role: editor # auto priority: 10
└─ role: subscriber # auto priority: 10
所以在基于角色和用户的层级关系加载策略
的模式下,最底层优先级最高,最顶层优先级最低。
最后
在使用Casbin做权限控制时,有了这些优先级模式的加持,让 Casbin 可以更灵活的应对各种各样的需求。
特别是在各种工作流/工单审批时,不同的用户有不同或相同的审批权限,可以做出不同的审批结果,当多人审批意见出现冲突时,那么就可以通过优先级来决定最终审批结果,谁的优先级高按谁的审批结果。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。