Priority Model
Casbin 可以给策略设置 优先级:多条策略匹配时,优先级最高的那条生效(可以产生允许或拒绝)。
隐式优先级(策略顺序)
策略的顺序决定优先级:列表中 最前面 的优先级最高。使用这个效果:
[policy_effect]
e = priority(p.eft) || deny
显式优先级(数值字段)
在策略中加一个 priority 字段;数值 越小 优先级 越高。非数值的值被视为最低优先级。见 casbin#550。
自定义优先级字段
默认的优先级字段名是 priority。使用其他名称(例如 customized_priority)时,在初始化后调用 e.SetFieldIndex("p", constant.PriorityIndex, index) 并重新加载策略。示例:TestCustomizedFieldIndex。
在策略中使用显式优先级的示例:
[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 修改优先级字段。
完整模型:
[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
主体优先级(角色 / 用户层级)
使用 subjectPriority(p.eft),让优先级来自 角色层级:叶子节点(例如最终用户)的优先级高于内部角色。层级必须是 树,不能是图;如果一个用户有多个角色,它们在各自的树中应处于同一深度。同一层级的冲突按策略顺序决定。见 casbin#833、casbin#831。
模型:
[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
Comments are powered by giscus and GitHub Discussions. They load from giscus.app and GitHub only after you click the button below.