Priority Model
O Casbin suporta o carregamento de políticas com prioridade.
Carregar Política com Prioridade Implícita
É bastante simples: a ordem determina a prioridade; políticas que aparecem primeiro têm prioridade mais alta.
model.conf:
[policy_effect]
e = priority(p.eft) || deny
Carregar Política com Prioridade Explícita
Também veja: casbin#550
Um valor de prioridade menor indica uma prioridade mais alta. Se houver um caractere não numérico na prioridade, ele será colocado por último em vez de gerar um erro.
O nome de token de prioridade convencionalmente usado na definição de política é "priority". Para usar um personalizado, você precisa invocar e.SetFieldIndex()
e recarregar as políticas (veja o exemplo completo em TestCustomizedFieldIndex).
model.conf:
[policy_definition]
p = customized_priority, sub, obj, act, eft
Exemplo de código em 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`
No momento, a prioridade explícita só suporta AddPolicy
& AddPolicies
. Se UpdatePolicy
foi chamado, você não deve mudar o atributo de prioridade.
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
requisição:
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
Carregar Política com Prioridade Baseada na Hierarquia de Papéis e Usuários
A estrutura herdada de papéis e usuários só pode ser múltiplas árvores, não grafos. Se um usuário tem múltiplos papéis, você tem que garantir que o usuário tenha o mesmo nível em diferentes árvores. Se dois papéis têm o mesmo nível, a política (associada ao papel) que apareceu primeiro tem prioridade mais alta. Para mais detalhes, também veja casbin#833 e 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
Requisição:
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
A hierarquia de papéis se parece com isto:
role: root
└─ role: admin
├─ role editor
│ └─ user: jane
│
└─ role: subscriber
└─ user: alice
A prioridade automaticamente se parece com isto:
role: root # auto priority: 30
└─ role: admin # auto priority: 20
├─ role: editor # auto priority: 10
└─ role: subscriber # auto priority: 10