Skip to content

Casbin

Offizielles Repository: casbin/casbin: An authorization library that supports access control models like ACL, RBAC, ABAC in Golang (github.com)

Offizielle Dokumentation: Überblick | Casbin

TIP

Dieser Artikel ist lediglich eine Einführung in Casbin. Für ein detaillierteres Verständnis besuchen Sie bitte die offizielle Website.

Einführung

In einem System sind Backend-Entwickler für die Verwaltung der API-Berechtigungen verantwortlich, was viel Arbeit erfordert. Wenn jedes Projekt eine eigene Berechtigungslogik implementieren müsste, würde dies viel Zeit verschwenden. Größere Unternehmen mit mehr Ressourcen entwickeln lieber ihre eigenen Berechtigungsframeworks, aber die meisten kleinen und mittleren Unternehmen können sich diese Entwicklungskosten nicht leisten, daher sind Open-Source-Berechtigungsframeworks ihre erste Wahl. Casbin ist eine solche Open-Source-Zugangskontrollbibliothek, die in Go entwickelt wurde und auch andere wichtige Programmiersprachen unterstützt.

Es ist wichtig zu beachten, dass Casbin nur ein Zugangskontrollframework ist und nur für die Zugangskontrolle verantwortlich ist. Die Authentifizierungslogik wird nicht von Casbin verwaltet; es speichert nur die Zuordnungsbeziehungen zwischen Benutzern und Rollen. Es unterstützt folgende Zugangskontrollmodelle:

  1. ACL (Access Control List, Zugangskontrollliste)
  2. ACL mit Superuser
  3. ACL ohne Benutzer: Besonders nützlich für Systeme ohne Authentifizierung oder Benutzeranmeldung.
  4. ACL ohne Ressourcen: In bestimmten Szenarien kann es nur um Ressourcentypen gehen, nicht um einzelne Ressourcen, wie Berechtigungen für write-article, read-log usw. Es kontrolliert nicht den Zugriff auf bestimmte Artikel oder Protokolle.
  5. RBAC (Rollenbasierte Zugangskontrolle)
  6. RBAC mit Ressourcenrollen: Benutzer und Ressourcen können gleichzeitig Rollen (oder Gruppen) haben.
  7. RBAC mit Domains/Tenants: Benutzer können für verschiedene Domains/Tenants unterschiedliche Rollensätze haben.
  8. ABAC (Attributbasierte Zugangskontrolle): Unterstützt die Nutzung syntaktischen Zuckers wie resource.Owner, um auf Attribute von Elementen zuzugreifen.
  9. RESTful: Unterstützt Pfade wie /res/*, /res/:id und HTTP-Methoden wie GET, POST, PUT, DELETE.
  10. Ablehnung vorrangig: Unterstützt Erlaubnis und Ablehnung bei der Autorisierung, wobei Ablehnung vor Erlaubnis geht.
  11. Priorität: Strategieeregeln werden nach ihrer Reihenfolge priorisiert, ähnlich wie Firewall-Regeln.

Funktionsweise

In Casbin wird das Zugangskontrollmodell als PERM-basierte Konfigurationsdatei abstrahiert. PERM steht für Policy (Strategie), Effect (Effekt), Request (Anfrage), Matcher (Vergleicher). Bei Änderungen der Autorisierungsmechanismen in einem Projekt muss nur die Konfigurationsdatei geändert werden. Eine normale Model-Konfigurationsdatei sieht wie folgt aus:

bash
[request_definition]
r = sub, obj, act

[policy_definition]
p = sub, obj, act

[policy_effect]
e = some(where (p.eft == allow))

[matchers]
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act

Dies ist ein einfaches ACL-Zugangskontrollmodell.

Strategie (Policy)

In der Konfigurationsdatei lautet der Strategie-Definitionsteil:

[policy_definition]
p = sub, obj, act

p steht für policy und kann nicht durch andere Zeichen ersetzt werden. sub steht für subject (Strategiesubjekt), obj für object (Strategieobjekt), act für action (Aktion).

p = sub, obj, act

Es kann auch ein viertes Feld eft geben; wenn weggelassen, ist eft standardmäßig allow.

p=sub, obj, act, eft

Diese Zeile beschreibt nur, wie eine Strategie geschrieben werden soll, nicht die konkrete Strategiedefinition. Hier ist ein konkretes Beispiel für eine Strategie:

p, jojo, cake, eat

p zeigt an, dass dies eine Strategie-Regeldefinition ist, jojo ist das Strategie-Subjekt, cake ist das Strategie-Objekt, eat ist die Aktion. Die vollständige Bedeutung ist: Das Subjekt jojo kann die Aktion eat auf dem Objekt cake ausführen. Die konkreten Strategieregeln erscheinen nicht in der Model-Datei, sondern werden in separaten Policy-Dateien oder Datenbanken gespeichert.

Anfrage (Request)

In der Konfigurationsdatei lautet der Anfrage-Definitionsteil:

[request_definition]
r = sub, obj, act

r steht für request und kann nicht durch andere Zeichen ersetzt werden. sub steht für subject (Anfragesubjekt), obj für object (Anfrageobjekt), act für action (Anfrageaktion). Normalerweise sind die Feldnamen der Anfragedefinition mit denen der Strategiedefinition identisch. Der Anfrage-Teil wird nicht von Casbin verwaltet; der Entwickler entscheidet selbst, was das Anfragesubjekt und das Anfrageobjekt ist. Casbin ist nur für die Zugangskontrolle basierend auf den übergebenen Feldern verantwortlich.

Matcher (Vergleicher)

In der Konfigurationsdatei lautet der Matcher-Definitionsteil:

[matchers]
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act

m steht für matcher und kann nicht durch andere Zeichen ersetzt werden. Danach folgen die entsprechenden Vergleichsregeln. Das Obige ist ein einfacher boolescher Ausdruck, der bedeutet: Alle Felder der eingehenden Anfrage stimmen mit den Feldern der Strategieregel überein. Es können auch Wildcards oder ausdrucksstärkere reguläre Ausdrücke verwendet werden.

Darüber hinaus unterstützt der Matcher auch die in-Syntax, zum Beispiel:

[matchers]
m = r.sub in ("root","admin")

Es kann auch sein:

[matchers]
m = r.sub.Name in (r.obj.Admins)
go
e.Enforce(Sub{Name: "alice"}, Obj{Name: "a book", Admins: []interface{}{"alice", "bob"}})

Beim Vergleich führt Casbin keine Typprüfung durch, sondern prüft als interface mit == auf Gleichheit.

Effekt (Effect)

Der Effekt-Definitionsteil trifft weitere logische Kombinationsentscheidungen für das Vergleichsergebnis. In der Konfigurationsdatei lautet der Effekt-Definitionsteil:

[policy_effect]
e = some(where (p.eft == allow))

e steht für effect und kann nicht durch andere Zeichen ersetzt werden. Der Quantor some prüft, ob es eine Strategieregel gibt, die dem Matcher entspricht. Der Quantor any prüft, ob alle Strategieregeln dem Matcher entsprechen.

some(where (p.eft == allow))

Diese Regel bedeutet: Wenn es in den Vergleichsergebnissen ein allow gibt, ist das Endergebnis allow.

e = !some(where (p.eft == deny))

Diese Regel bedeutet: Wenn es in den Vergleichsergebnissen kein deny gibt, ist das Endergebnis allow.

e = some(where (p.eft == allow)) && !some(where (p.eft == deny))

Diese Regel bedeutet: Wenn es in den Vergleichsergebnissen ein allow gibt und kein deny, ist das Endergebnis allow.

Obwohl Casbin die oben genannte Syntax für Richtlinieneffekte entworfen hat, verwendet die aktuelle Ausführung nur hartcodierte Richtlinieneffekte. Es wird angenommen, dass diese Flexibilität nicht sehr notwendig ist. Bis jetzt müssen Sie die integrierten Policy-Effects verwenden und können diese nicht anpassen. Die unterstützten integrierten Policy-Effects sind:

Policy-Effect-DefinitionBedeutungBeispiel
some(where (p.eft == allow))allow-overrideACL, RBAC, etc.
!some(where (p.eft == deny))deny-overrideAblehnung überschreiben
some(where (p.eft == allow)) && !some(where (p.eft == deny))allow-and-denyErlauben und Ablehnen
priority(p.eft) || denypriorityPriorität
subjectPriority(p.eft)rollenbasierte PrioritätSubjekt-Priorität

TIP

  1. Alle vier Definitionen können mehrfach definiert werden, die Syntax ist type+number, zum Beispiel r2, p2, e2, m2.

  2. Model-Dateien können Kommentare enthalten, die mit # eingeleitet werden.

Beispiel

Hier ist ein Beispiel, das den Arbeitsprozess der Model-Datei demonstriert. Zuerst definieren wir eine einfache ACL-Model-Datei:

[request_definition]
r = sub, obj, act

[policy_definition]
p = sub, obj, act

[policy_effect]
e = some(where (p.eft == allow))

[matchers]
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act

Die Policy-Datei sieht wie folgt aus:

p, alice, data1, read
p, bob, data2, write

Wie Subjekt, Objekt und Aktion abstrahiert werden, wird durch die Geschäftslogik bestimmt und ist hier nicht wichtig, daher wird es weggelassen. Im Folgenden werden die eingehenden Anfragen auf einfachste Weise dargestellt:

alice, data1, read
bob, data1, read
alice, data2, write
bob, data2, write

Die Policy-Datei definiert, dass alice die Berechtigung hat, data1 zu lesen, und bob die Berechtigung hat, data2 zu schreiben. Bei den eingehenden Anfragen:

alice, data1, read

bedeutet, dass alice eine read-Operation auf data1 durchführen möchte.

bob, data1, read

bedeutet, dass bob eine read-Operation auf data1 durchführen möchte. Der Rest ist analog. Das Endergebnis lautet:

true
false
false
true

Dies ist ein einfaches ACL-Beispiel. Auf der Casbin-Website können Sie Beispiele online bearbeiten und testen. Besuchen Sie Casbin editor zum Testen.

RBAC

RBAC (Role-Based-Access-Control), rollenbasierte Zugangskontrolle, hat im Vergleich zum ACL-Modell eine zusätzliche [role_definition]. Hier ist ein einfaches RBAC-Modell:

[request_definition]
r = sub, obj, act

[policy_definition]
p = sub, obj, act

[role_definition]
g = _, _

[policy_effect]
e = some(where (p.eft == allow))

[matchers]
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act

Die Rollendefinition lautet:

[role_definition]
g = _, _

g steht für group und kann nicht durch andere Zeichen ersetzt werden. Es unterstützt die type+number-Methode zur Erstellung mehrerer Definitionen. _ ist ein Platzhalter, der angibt, wie viele Eingabeparameter es gibt. Normalerweise hat g in der Policy folgendes Format:

g, alice, data2_admin
g, mike, data1_admin
g, data1_admin data2_admin

alice bezieht sich auf das Subjekt, data2_admin auf die Rolle. Streng genommen betrachtet Casbin alles als Zeichenketten; wie sie verstanden und verwendet werden, hängt vom Entwickler ab.

g, alice, data2_admin

bedeutet, dass alice die Rolle data2_admin hat.

g, mike, data1_admin

bedeutet, dass mike die Rolle data1_admin hat.

g, data1_admin data2_admin

bedeutet, dass die Rolle data1_admin die Rolle data2_admin hat. Dies ist eine Vererbungsbeziehung zwischen Rollen.

Ressourcenrollen-Modell

Das Ressourcenrollen-Modell fügt ein g2 als Ressourcenrollendefinition hinzu. Die Modelldefinition lautet:

[request_definition]
r = sub, obj, act

[policy_definition]
p = sub, obj, act

[role_definition]
g = _, _
g2 = _, _

[policy_effect]
e = some(where (p.eft == allow))

[matchers]
m = g(r.sub, p.sub) && g2(r.obj, p.obj) && r.act == p.act

Ein Beispiel für die Policy-Definition:

p, alice, data1, read
p, bob, data2, write
p, data_group_admin, data_group, write

g, alice, data_group_admin
g2, data1, data_group
g2, data2, data_group

g2 definiert Ressourcenrollengruppen und weist Ressourcen verschiedenen Rollen zu. Gleichzeitig werden die Benutzerbeziehungen zwischen Benutzerrollen und Ressourcenrollen definiert.

p, data_group_admin, data_group, write

Diese Strategie definiert, dass Benutzer mit der Rolle data_group_admin Schreiboperationen auf Ressourcen mit der Rolle data_group durchführen können.

Multi-Tenant-Domain-Modell

[request_definition]
r = sub, dom, obj, act

[policy_definition]
p = sub, dom, obj, act

[role_definition]
g = _, _, _

[policy_effect]
e = some(where (p.eft == allow))

[matchers]
m = g(r.sub, p.sub, r.dom) && r.dom == p.dom && r.obj == p.obj && r.act == p.act

Das Multi-Tenant-Domain-Modell hat im Vergleich zum traditionellen RBAC-Modell ein zusätzliches dom-Feld, das die Domain angibt, zu der das Subjekt gehört. Ein Beispiel für die Policy:

p, admin, domain1, data1, read
p, admin, domain1, data1, write
p, admin, domain2, data2, read
p, admin, domain2, data2, write

g, alice, admin, domain1
g, bob, admin, domain2

Zum Beispiel:

p, admin, domain1, data1, read

definiert, dass das Subjekt admin in der Domain domain1 die Berechtigung hat, data1 zu lesen.

g, alice, admin, domain1

definiert, dass alice zur Domain domain1 gehört und die Rolle admin hat.

ABAC

Golang by www.golangdev.cn edit