动态

详情 返回 返回

利用 PHP-Casbin 中的優先級模型來做權限控制 - 动态 详情

優先級模型,所謂優先級,是指按一定的順序加載策略。

優先級高的策略先加載,先加載的策略具有較高的優先級。

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有三種取值:allowdenyindeterminate

顯示優先順序加載策

參考官方文檔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所屬的角色editordata1read是拒絕的(deny),並且位置靠前,但jane本身有一條對data1read的允許allow策略,即便位置靠後,janedata1read 仍然為 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 可以更靈活的應對各種各樣的需求。

特別是在各種工作流/工單審批時,不同的用户有不同或相同的審批權限,可以做出不同的審批結果,當多人審批意見出現衝突時,那麼就可以通過優先級來決定最終審批結果,誰的優先級高按誰的審批結果。

user avatar zhuifengdekaomianbao 头像 maimengdexiangjiao 头像 kukudejiqimao_bns3pe 头像 tecdat 头像 seth9shi 头像 headofhouchang 头像 phpercode 头像 aoshunseo 头像 tangzhangming 头像 huaming 头像 49u7s8yz 头像 rongyunrongcloud 头像
点赞 16 用户, 点赞了这篇动态!
点赞

Add a new 评论

Some HTML is okay.