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`
目前,显式优先级仅支持AddPolicy
和AddPolicies
。 如果已经调用了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#833和casbin#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