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