Priority Model
Casbin soporta la carga de políticas con prioridad.
Cargar Política con Prioridad Implícita
Es bastante simple: el orden determina la prioridad; las políticas que aparecen primero tienen mayor prioridad.
model.conf:
[policy_effect]
e = priority(p.eft) || deny
Cargar Política con Prioridad Explícita
También ver: casbin#550
Un valor de prioridad menor indica una mayor prioridad. Si hay un carácter no numérico en la prioridad, se colocará al final en lugar de lanzar un error.
El nombre de token de prioridad convencionalmente utilizado en la definición de la política es "priority". Para usar uno personalizado, necesitas invocar e.SetFieldIndex()
y recargar las políticas (ver el ejemplo completo en 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`
Actualmente, la prioridad explícita solo soporta AddPolicy
& AddPolicies
. Si se ha llamado a UpdatePolicy
, no deberías cambiar el atributo de prioridad.
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
La estructura heredada de roles y usuarios solo puede ser múltiples árboles, no gráficos. Si un usuario tiene múltiples roles, tienes que asegurarte de que el usuario tenga el mismo nivel en diferentes árboles. Si dos roles tienen el mismo nivel, la política (asociada con el rol) que apareció primero tiene mayor prioridad. Para más detalles, también ver casbin#833 y 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
La jerarquía de roles se ve así:
role: root
└─ role: admin
├─ role editor
│ └─ user: jane
│
└─ role: subscriber
└─ user: alice
La prioridad automáticamente se ve así:
role: root # auto priority: 30
└─ role: admin # auto priority: 20
├─ role: editor # auto priority: 10
└─ role: subscriber # auto priority: 10