ABAC
Cos'è il modello ABAC?
ABAC sta per Attribute-Based Access Control. Ti consente di controllare l'accesso utilizzando gli attributi (proprietà) del soggetto, dell'oggetto o dell'azione invece di utilizzare i valori stringa stessi. Potresti aver sentito parlare di un complesso linguaggio di controllo degli accessi ABAC chiamato XACML. D'altra parte, Casbin's ABAC è molto più semplice. In Casbin's ABAC, puoi utilizzare strutture o istanze di classe invece di stringhe per gli elementi del modello.
Diamo un'occhiata all'esempio ufficiale di ABAC:
[request_definition]
r = sub, obj, act
[policy_definition]
p = sub, obj, act
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = r.sub == r.obj.Owner
Nel matcher, utilizziamo r.obj.Owner
invece di r.obj
. Il r.obj
passato nella funzione Enforce()
sarà una struttura o un'istanza di classe piuttosto che una stringa. Casbin utilizzerà la riflessione per recuperare la variabile membro obj
in quella struttura o classe per te.
Ecco una definizione per la struttura o la classe r.obj
:
type testResource struct {
Name string
Owner string
}
Se desideri passare parametri all'enforcer attraverso JSON, devi abilitare la funzione con e.EnableAcceptJsonRequest(true)
.
Ad esempio:
e, _ := NewEnforcer("examples/abac_model.conf")
e.EnableAcceptJsonRequest(true)
data1Json := `{ "Name": "data1", "Owner": "bob"}`
ok, _ := e.Enforce("alice", data1Json, "read")
Abilitare la funzione di accettazione dei parametri JSON potrebbe causare un calo delle prestazioni da 1,1 a 1,5 volte.
Come utilizzare ABAC?
Per utilizzare ABAC, è necessario fare due cose:
- Specificare gli attributi nel matcher del modello.
- Passare l'istanza della struttura o della classe per l'elemento come argomento alla funzione
Enforce()
di Casbin.
Attualmente, solo gli elementi della richiesta come r.sub
, r.obj
, r.act
e così via supportano ABAC. Non è possibile utilizzarlo su elementi di policy come p.sub
perché non c'è modo di definire una struttura o una classe nella policy di Casbin.
Puoi utilizzare più attributi ABAC in un matcher. Ad esempio: m = r.sub.Domain == r.obj.Domain
.
Se hai bisogno di utilizzare una virgola in una policy che entra in conflitto con il separatore del CSV, puoi evitare il conflitto racchiudendo la dichiarazione tra virgolette. Ad esempio, "keyMatch("bob", r.sub.Role)"
non verrà diviso.
Scalare il modello per regole ABAC complesse e numerose
L'implementazione sopra descritta del modello ABAC è semplice nel suo nucleo. Tuttavia, in molti casi, il sistema di autorizzazione richiede un numero complesso e grande di regole ABAC. Per soddisfare questo requisito, si raccomanda di aggiungere le regole nella politica invece che nel modello. Questo può essere fatto introducendo un costrutto funzionale eval()
. Ecco un esempio:
Questa è la definizione del file CONF
utilizzato per definire il modello ABAC.
[request_definition]
r = sub, obj, act
[policy_definition]
p = sub_rule, obj, act
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = eval(p.sub_rule) && r.obj == p.obj && r.act == p.act
In questo esempio, p.sub_rule
è una struttura o classe (tipo definito dall'utente) che contiene gli attributi necessari da utilizzare nella politica.
Questa è la politica che viene utilizzata contro il modello per Enforcement
. Ora, puoi utilizzare l'istanza dell'oggetto passata a eval()
come parametro per definire determinati vincoli ABAC.
p, r.sub.Age > 18, /data1, read
p, r.sub.Age < 60, /data2, write