Ir al contenido principal

Priority Model

Casbin supports priority-based policy loading.

Cargar Política con Prioridad Implícita

Priority is determined by policy order: policies appearing first have higher priority.

model.conf:

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

Cargar Política con Prioridad Explícita

See also: casbin#550

Lower priority values indicate higher priority. Non-numerical priority values are placed last rather than causing errors.

Convención de nombres de tokens

The standard priority token name in policy definitions is "priority". To use a custom token name, call e.SetFieldIndex() after initializing the enforcer and reload policies (see the full example in TestCustomizedFieldIndex).

model.conf:

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

Ejemplo de código en 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`

Explicit priority currently supports only AddPolicy and AddPolicies. Avoid changing the priority attribute when calling 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

solicitud:

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

Cargar Política con Prioridad Basada en Jerarquía de Rol y Usuario

The role and user inheritance structure must form multiple trees, not graphs. When a user has multiple roles, ensure the user occupies the same hierarchy level in each tree. When two roles share the same level, the policy appearing first takes priority. For details, see casbin#833 and 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

Solicitud:

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

The role hierarchy structure:

role: root
└─ role: admin
├─ role editor
│ └─ user: jane

└─ role: subscriber
└─ user: alice

Automatic priority assignment:

role: root                 # auto priority: 30
└─ role: admin # auto priority: 20
├─ role: editor # auto priority: 10
└─ role: subscriber # auto priority: 10