Casbin
Dépôt officiel : casbin/casbin: An authorization library that supports access control models like ACL, RBAC, ABAC in Golang (github.com)
Documentation officielle : Présentation | Casbin
TIP
Cet article ne constitue qu'une introduction à Casbin. Pour une compréhension plus approfondie, veuillez consulter la documentation officielle.
Introduction
Dans un système, les développeurs backend sont responsables de la gestion des permissions API, ce qui nécessite un travail considérable. Si chaque projet doit développer sa propre solution, cela représentera une perte de temps importante. Les grandes entreprises disposant de plus de ressources humaines et matérielles ont tendance à développer leur propre framework de permissions, mais la plupart des PME ne peuvent pas supporter ces coûts de développement. Les frameworks de permissions open source du marché deviennent donc leur premier choix. Casbin est une telle bibliothèque de contrôle d'accès open source et efficace, développée en Go, tout en supportant d'autres langages populaires.
Il est important de noter que Casbin est uniquement un framework de contrôle d'accès, responsable uniquement du contrôle d'accès. La logique d'authentification n'est pas gérée par Casbin, qui stocke uniquement les relations de mappage entre utilisateurs et rôles. Il supporte les modèles de contrôle d'accès suivants :
- ACL (Access Control List, liste de contrôle d'accès)
- ACL avec super utilisateur
- ACL sans utilisateur : particulièrement utile pour les systèmes sans authentification ou connexion utilisateur.
- ACL sans ressource : certains scénarios peuvent concerner uniquement les types de ressources, pas les ressources individuelles, comme les permissions
write-article,read-log. Cela ne contrôle pas l'accès à un article ou un journal spécifique. - RBAC (contrôle d'accès basé sur les rôles)
- RBAC avec rôles de ressources : les utilisateurs et les ressources peuvent tous deux avoir des rôles (ou groupes).
- RBAC avec domaines/locataires : les utilisateurs peuvent avoir différents ensembles de rôles pour différents domaines/locataires.
- ABAC (contrôle d'accès basé sur les attributs) : supporte l'utilisation de sucres syntaxiques comme
resource.Ownerpour obtenir les attributs des éléments. - RESTful : supporte les chemins comme
/res/*,/res/: idet les méthodes HTTP commeGET,POST,PUT,DELETE. - Refus prioritaire : supporte l'autorisation allow et deny, le refus prime sur l'autorisation.
- Priorité : les règles de stratégie déterminent la priorité selon leur ordre d'apparition, similaire aux règles de pare-feu.
Principe de fonctionnement
Dans Casbin, le modèle de contrôle d'accès est abstrait en fichiers de configuration basés sur PERM. PERM désigne Policy (stratégie), Effect (effet), Request (requête), Matcher (correspondance). Lors de la modification du mécanisme d'autorisation dans un projet, il suffit de modifier le fichier de configuration. Un fichier de configuration de modèle standard ressemble à ceci :
[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.actC'est un modèle de contrôle d'accès ACL très simple.
Stratégie
Dans le fichier de configuration, la partie définition de stratégie est :
[policy_definition]
p = sub, obj, actp désigne policy, ne peut pas être remplacé par d'autres caractères, sub désigne subject (sujet de la stratégie), obj désigne object (objet de la stratégie), act désigne action (comportement).
p = sub, obj, actIl peut aussi y avoir un quatrième champ eft, s'il est omis, eft est par défaut allow.
p=sub, obj, act, eftCette ligne de définition décrit uniquement comment écrire la policy, ce n'est pas une définition de stratégie concrète. Voici un exemple de policy concrète :
p, jojo, cake, eatp indique qu'il s'agit d'une définition de règle de stratégie, jojo est le sujet de la stratégie, cake est l'objet de la stratégie, eat est le comportement. Le sens complet est que le sujet jojo peut effectuer l'action eat sur l'objet cake. Les règles de stratégie concrètes n'apparaissent pas dans le fichier de modèle, il existe des fichiers policy dédiés ou des bases de données pour stocker les stratégies.
Requête
Dans le fichier de configuration, la partie définition de requête est :
[request_definition]
r = sub, obj, actr désigne request, ne peut pas être remplacé par d'autres caractères, sub désigne subject (sujet de la requête), obj désigne object (objet de la requête), act désigne action (comportement de la requête). En général, les noms de champs de la définition de requête sont identiques à ceux de la définition de stratégie. La partie requête n'est pas gérée par Casbin, c'est au développeur de décider ce qu'est le sujet de la requête, l'objet de la requête. Casbin se contente d'effectuer le contrôle d'accès en fonction des champs passés.
Correspondance
Dans le fichier de configuration, la partie définition de correspondance est :
[matchers]
m = r.sub == p.sub && r.obj == p.obj && r.act == p.actm désigne matcher, ne peut pas être remplacé par d'autres caractères, suivi des règles de correspondance correspondantes. L'expression ci-dessus est une simple expression booléenne signifiant que tous les champs de la requête passée correspondent aux champs de la règle de stratégie. Elle peut aussi être des caractères génériques ou des expressions régulières plus expressives.
De plus, matcher supporte la syntaxe in, par exemple :
[matchers]
m = r.sub in ("root","admin")Ou encore :
[matchers]
m = r.sub.Name in (r.obj.Admins)e.Enforce(Sub{Name: "alice"}, Obj{Name: "a book", Admins: []interface{}{"alice", "bob"}})Lors de la correspondance, Casbin ne effectue pas de vérification de type, mais compare en tant que interface avec ==.
Effet
La partie définition de l'effet effectue à nouveau des jugements de combinaison logique sur les résultats de correspondance. Dans le fichier de configuration, la partie définition de l'effet est :
[policy_effect]
e = some(where (p.eft == allow))e désigne effect, ne peut pas être remplacé par d'autres caractères. Le quantificateur some détermine s'il existe au moins une règle de stratégie qui satisfait le matcher. Le quantificateur any détermine si toutes les règles de stratégie satisfont le matcher.
some(where (p.eft == allow))Cette règle signifie que s'il y a un résultat allow dans les résultats de correspondance, le résultat final est allow.
e = !some(where (p.eft == deny))Cette règle signifie que s'il n'y a pas de résultat deny dans les résultats de correspondance, le résultat final est allow.
e = some(where (p.eft == allow)) && !some(where (p.eft == deny))Cette règle signifie que s'il y a un résultat allow dans les résultats de correspondance, et qu'il n'y a pas de résultat deny, le résultat final est allow.
Bien que Casbin ait conçu la syntaxe ci-dessus pour les effets de politique, l'exécution actuelle utilise uniquement des effets de politique codés en dur. Ils considèrent que cette flexibilité n'est pas vraiment nécessaire. Jusqu'à présent, vous devez utiliser les effets de politique intégrés, vous ne pouvez pas les personnaliser. Les effets de politique intégrés supportés sont les suivants.
| Définition de l'effet de politique | Signification | Exemple |
|---|---|---|
| some(where (p.eft == allow)) | allow-override | ACL, RBAC, etc. |
| !some(where (p.eft == deny)) | deny-override | Refus prioritaire |
| some(where (p.eft == allow)) && !some(where (p.eft == deny)) | allow-and-deny | Autorisation et refus |
| priority(p.eft) || deny | priority | Priorité |
| subjectPriority(p.eft) | priorité basée sur les rôles | Priorité de sujet |
TIP
Les quatre définitions ci-dessus peuvent toutes être définies plusieurs fois, la syntaxe est
type+number, par exempler2,p2,e2,m2.Le fichier de modèle peut avoir des commentaires, utilisant le symbole
#.
Exemple
Voici un exemple démontrant le fonctionnement du fichier de modèle. D'abord, définissons un fichier de modèle ACL simple comme suit :
[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.actLe fichier Policy est le suivant :
p, alice, data1, read
p, bob, data2, writeComment abstraire le sujet, l'objet, le comportement est décidé par la logique métier, ce n'est pas important ici donc omis. Voici les requêtes passées de la manière la plus simple :
alice, data1, read
bob, data1, read
alice, data2, write
bob, data2, writeLe fichier policy définit qu'alice a la permission de faire une opération read sur data1, bob a la permission de faire une opération write sur data2, donc dans les requêtes passées :
alice, data1, readSignifie qu'alice veut faire une opération read sur data1,
bob, data1, readSignifie que bob veut faire une opération read sur data1, le reste est similaire. Le résultat final est :
true
false
false
trueC'est un exemple ACL très simple. Vous pouvez éditer et tester des exemples en ligne sur le site officiel de Casbin, rendez-vous sur Casbin editor pour tester.
RBAC
RBAC (Role-Based-Access-Controll), contrôle d'accès basé sur les rôles. Comparé au modèle ACL, il y a une section [role_definition] supplémentaire. Voici un modèle RBAC simple :
[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.actLa définition du rôle est la suivante :
[role_definition]
g = _, _g désigne group, ne peut pas être remplacé par d'autres caractères, supporte la création de multiples avec type+number, _ est un espace réservé indiquant le nombre de paramètres entrants. En général, dans Policy, g est généralement au format suivant :
g, alice, data2_admin
g, mike, data1_admin
g, data1_admin data2_adminalice désigne le sujet, data2_admin désigne le rôle. Strictement parlant, Casbin les considère tous comme des chaînes de caractères. Comment comprendre leur signification et leur utilisation dépend des développeurs.
g, alice, data2_adminSignifie qu'alice a le rôle data2_admin
g, mike, data1_adminSignifie que mike a le rôle data1_admin
g, data1_admin data2_adminSignifie que le rôle data1_admin a le rôle data2_admin, c'est une relation d'héritage entre rôles.
Modèle de rôle de ressource
Le modèle de rôle de ressource ajoute un g2 comme définition de rôle de ressource. La définition du modèle est la suivante :
[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.actExemple de définition Policy :
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_groupg2 définit un groupe de rôles de ressources, attribuant différents rôles aux ressources, tout en définissant les relations entre les rôles utilisateurs et les rôles ressources.
p, data_group_admin, data_group, writeCette stratégie définit qu'un utilisateur avec le rôle data_group_admin peut effectuer une opération d'écriture sur une ressource ayant le rôle data_group.
Modèle de domaine multi-locataires
[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.actLe modèle de domaine multi-locataires a un champ dom supplémentaire par rapport au modèle RBAC traditionnel, utilisé pour représenter le domaine auquel appartient le sujet. Exemple de 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, domain2Par exemple :
p, admin, domain1, data1, readDéfinit que le sujet admin appartenant au domaine domain1 a la permission de faire une opération read sur data1
g, alice, admin, domain1Définit qu'alice appartient à domain1 et a le rôle admin
