跳转至主要内容

Priority Model

Casbin支持加载具有优先级的策略。

以隐式优先级加载策略

这非常简单:顺序决定了优先级;出现得越早的策略优先级越高。

model.conf:

[policy_effect]
e = priority(p.eft) || deny

以显式优先级加载策略

另见:casbin#550

优先级值越小,优先级越高。 如果优先级中有非数字字符,它将被放在最后,而不是抛出错误。

令牌名称约定

在策略定义中通常使用的优先级令牌名称是“priority”。 要使用自定义的,你需要调用e.SetFieldIndex()并重新加载策略(参见TestCustomizedFieldIndex的完整示例)。

model.conf:

[policy_definition]
p = customized_priority, sub, obj, act, eft

Golang代码示例:

e, _ := NewEnforcer("./example/priority_model_explicit_customized.conf",
"./example/priority_policy_explicit_customized.csv")
// Due to the customized priority token, the enforcer fails to handle the priority.
ok, err := e.Enforce("bob", "data2", "read") // the result will be `true, nil`
// Set PriorityIndex and reload
e.SetFieldIndex("p", constant.PriorityIndex, 0)
err := e.LoadPolicy()
if err != nil {
log.Fatalf("LoadPolicy: %v", err)
}
ok, err := e.Enforce("bob", "data2", "read") // the result will be `false, nil`

目前,显式优先级仅支持AddPolicyAddPolicies。 如果已经调用了UpdatePolicy,你不应该更改优先级属性。

model.conf:

[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.csv

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

根据角色和用户层次结构加载具有优先级的策略

角色和用户的继承结构只能是多棵树,不能是图。 如果一个用户有多个角色,你必须确保用户在不同的树中有相同的级别。 如果两个角色有相同的级别,那么先出现的策略(与角色关联)具有更高的优先级。 更多详情,另见casbin#833casbin#831

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.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

角色层次结构看起来像这样:

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