Understanding How Casbin Matching Works in Detail
In questo post, spiegherò la progettazione e l'implementazione di RBAC utilizzando la libreria Casbin. Per una piattaforma SaaS che gestisce più gerarchie di risorse e ruoli che ereditano permessi da livelli superiori, Casbin offre un'alternativa performante da considerare.
Introduzione a RBAC
RBAC è un metodo per limitare l'accesso alle risorse in base ai ruoli detenuti dagli individui. Per comprendere meglio come funziona il RBAC gerarchico, diamo un'occhiata al sistema RBAC di Azure nella prossima sezione e poi proviamo a implementare un sistema simile.
Comprendere il RBAC Gerarchico di Azure
C'è un ruolo chiamato Proprietario per tutte le risorse in Azure. Supponiamo che se ho il ruolo di Proprietario assegnato a me a livello di sottoscrizione, ciò significa che sono il Proprietario di tutti i gruppi di risorse e risorse sotto quella sottoscrizione. Se ho Proprietario a livello di gruppo di risorse, allora sono il Proprietario di tutte le risorse sotto quel gruppo di risorse.
Questa immagine mostra che ho accesso di Proprietario a livello di sottoscrizione.
Quando controllo l'IAM di un Gruppo di Risorse sotto questa Sottoscrizione, puoi vedere che ho ereditato l'accesso di Proprietario dalla sottoscrizione.
Quindi, ecco come il Controllo degli Accessi Basato sui Ruoli (RBAC) di Azure è gerarchico. La maggior parte del software aziendale utilizza RBAC gerarchico a causa della natura gerarchica dei livelli delle risorse. In questo tutorial, cercheremo di implementare un sistema simile utilizzando Casbin.
Come Funziona Casbin?
Prima di immergersi nell'implementazione, è importante capire cos'è Casbin e come funziona a un livello generale. Questa comprensione è necessaria perché ogni sistema di Controllo degli Accessi Basato sui Ruoli (RBAC) può variare in base a specifiche esigenze. Comprendendo il funzionamento di Casbin, possiamo effettivamente ottimizzare il modello.
Cos'è ACL?
ACL sta per Access Control List (Lista di Controllo degli Accessi). È un metodo in cui gli utenti sono mappati alle azioni e le azioni alle risorse.
La definizione del modello
Consideriamo un semplice esempio di un modello ACL.
[request_definition]
r = sub, act, obj
[policy_definition]
p = sub, act, obj
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act
Il request_definition è il modello di query del sistema. Ad esempio, una richiesta
alice, write, data1
può essere interpretata come "Può il soggetto Alice eseguire l'azione 'write' sull'oggetto 'data1'?"Il policy_definition è il modello di assegnazione del sistema. Ad esempio, creando una policy
alice, write, data1
, stai assegnando il permesso al soggetto Alice di eseguire l'azione 'write' sull'oggetto 'data1'.Il policy_effect definisce l'effetto della policy.
Nella sezione matchers, la richiesta viene confrontata con la policy utilizzando le condizioni
r.sub == p.sub && r.obj == p.obj && r.act == p.act
.
Ora testiamo il modello sull'editor di Casbin
Apri l'editor e incolla il modello sopra descritto nell'editor del Modello.
Incolla il seguente testo nell'editor delle Policy:
p, alice, read, data1
p, bob, write, data2
e il seguente nell'editor delle Richieste:
alice, read, data1
Il risultato sarà:
true
Rappresentazione visiva del modello ACL, della policy e della corrispondenza della richiesta
Cos'è RBAC?
RBAC sta per Role-Based Access Control. In RBAC, a un utente viene assegnato un ruolo per una risorsa, e un ruolo può contenere azioni arbitrarie. La richiesta verifica quindi se l'utente ha il permesso di eseguire l'azione sulla risorsa.
La definizione del modello
Consideriamo un semplice esempio di modello RBAC:
[request_definition]
r = sub, act, obj
[policy_definition]
p = sub, act, obj
[role_definition]
g = _, _
g2 = _, _
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = r.sub == p.sub && g(p.act, r.act) && r.obj == p.obj
- Il role_definition è un costruttore di relazioni grafiche che utilizza un Grafo per confrontare l'oggetto richiesta con l'oggetto politica.
Ora testiamo il modello sull'editor Casbin
Apri l'editor e incolla il modello sopra nell'editor del Modello.
Incolla quanto segue nell'editor della Politica:
p, alice, reader, data1
p, bob, owner, data2
g, reader, read
g, owner, read
g, owner, write
e quanto segue nell'editor della Richiesta:
alice, read, data1
alice, write, data1
bob, write, data2
bob, read, data2
bob, write, data1
Il risultato sarà:
true
false
true
true
false
Rappresentazione visiva del modello RBAC, della politica e del matching della richiesta
La tabella g - Mapping del ruolo all'azione ha un Grafo che mappa il ruolo all'azione. Questo Grafico può essere codificato come una lista di archi, come mostrato nella politica che è un modo comune di rappresentare un Grafico:
g, reader, read
g, owner, read
g, owner, write
p indica una normale politica che può essere confrontata utilizzando l'operatore ==. g è una funzione di confronto basata su Grafici. Puoi definire più comparatori di Grafici aggiungendo un suffisso numerico come g, g2, g3, ... e così via.
Che cos'è RBAC gerarchico?
In RBAC gerarchico, ci sono più di un tipo di risorse e c'è una relazione di ereditarietà tra i tipi di risorse. Ad esempio, "subscription" è un tipo e "resourceGroup" è un altro tipo. Una sub1 di tipo Subscription può contenere più resourceGroups (rg1, rg2) di tipo ResourceGroup.
Similmente alla gerarchia delle risorse, ci saranno due tipi di ruoli e azioni: ruoli e azioni di Subscription, e ruoli e azioni di ResourceGroup. C'è una relazione arbitraria tra il ruolo di Subscription e il ruolo di ResourceGroup. Ad esempio, considera un ruolo di sottoscrizione sub-owner. Questo ruolo è ereditato da un ruolo di ResourceGroup rg-owner, il che significa che se mi viene assegnato il ruolo sub-owner sulla sottoscrizione sub1, allora ottengo automaticamente anche il ruolo rg-owner su rg1 e rg2.
La definizione del modello
Prendiamo un semplice esempio del modello Hierarchical RBAC:
[request_definition]
r = sub, act, obj
[policy_definition]
p = sub, act, obj
[role_definition]
g = _, _
g2 = _, _
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = r.sub == p.sub && g(p.act, r.act) && g2(p.obj, r.obj)
- La role_definition è un costruttore di relazioni grafiche che utilizza un grafo per confrontare l'oggetto richiesta con l'oggetto politica.
Ora testiamo il modello sull'editor Casbin
Apri l'editor e incolla il modello sopra nell'editor del Modello.
Incolla quanto segue nell'editor della Politica:
p, alice, sub-reader, sub1
p, bob, rg-owner, rg2
// subscription role to subscription action mapping
g, sub-reader, sub-read
g, sub-owner, sub-read
g, sub-owner, sub-write
// resourceGroup role to resourceGroup action mapping
g, rg-reader, rg-read
g, rg-owner, rg-read
g, rg-owner, rg-write
// subscription role to resourceGroup role mapping
g, sub-reader, rg-reader
g, sub-owner, rg-owner
// subscription resource to resourceGroup resource mapping
g2, sub1, rg1
g2, sub2, rg2
E incolla quanto segue nell'editor della Richiesta:
alice, rg-read, rg1
Il risultato sarà:
true
Rappresentazione visiva del modello RBAC, della politica e della corrispondenza delle richieste
La tabella g - Mapping del Ruolo a (Azione, Ruolo) ha un grafico che mappa il ruolo all'azione, al mapping del ruolo. Questo grafico può essere codificato come una lista di archi, come mostrato nella politica, che è un modo comune di rappresentare un grafico:
// subscription role to subscription action mapping
g, sub-reader, sub-read
g, sub-owner, sub-read
g, sub-owner, sub-write
// resourceGroup role to resourceGroup action mapping
g, rg-reader, rg-read
g, rg-owner, rg-read
g, rg-owner, rg-write
// subscription role to resourceGroup role mapping
g, sub-reader, rg-reader
g, sub-owner, rg-owner
La tabella g2 - Mapping di Sottoscrizione a RG ha un grafico che mappa la sottoscrizione al gruppo di risorse:
// subscription resource to resourceGroup resource mapping
g2, sub1, rg1
g2, sub2, rg2
Rappresentazione visiva della corrispondenza del soggetto
Rappresentazione visiva della corrispondenza dell'azione
Rappresentazione visiva della corrispondenza dell'oggetto
Quando una richiesta viene inviata a Casbin, questa corrispondenza avviene per tutte le politiche. Se almeno una politica corrisponde, allora il risultato della richiesta è vero. Se nessuna politica corrisponde alla richiesta, allora il risultato è falso.
Conclusione
In questo tutorial, abbiamo imparato come funzionano diversi modelli di autorizzazione e come possono essere modellati utilizzando Casbin. Nella seconda parte di questo tutorial, implementeremo questo in una demo di applicazione Spring Boot e proteggiamo le API utilizzando Casbin.