Casbin
Repositorio oficial: casbin/casbin: An authorization library that supports access control models like ACL, RBAC, ABAC in Golang (github.com)
Documentación oficial: Overview | Casbin
TIP
Este artículo solo puede considerarse como una introducción a Casbin. Si desea obtener más información detallada, visite el sitio web oficial.
Introducción
En un sistema, los programadores backend necesitan ser responsables de la gestión de permisos de API, lo que requiere una gran cantidad de trabajo. Si cada proyecto necesita escribir su propio sistema desde cero, se perderá mucho tiempo. Las grandes empresas con más recursos humanos y materiales estarán más inclinadas a desarrollar su propio marco de permisos, pero la mayoría de las pequeñas y medianas empresas no pueden soportar este costo de desarrollo, por lo que los marcos de permisos de código abierto en el mercado se convierten en su primera opción. Casbin es precisamente una biblioteca de control de acceso abierta y eficiente, desarrollada en Go, y también soporta otros lenguajes principales.
Es importante tener en cuenta que Casbin es solo un marco de control de acceso, solo es responsable del control de acceso, la lógica de autenticación de acceso no es responsabilidad de Casbin, solo almacena la relación de mapeo entre usuarios y roles. Soporta los siguientes modelos de control de acceso:
- ACL (Access Control List, Lista de Control de Acceso)
- ACL con superusuario
- ACL sin usuarios: especialmente útil para sistemas sin autenticación o inicio de sesión de usuario.
- ACL sin recursos: algunos escenarios pueden estar dirigidos solo a tipos de recursos, en lugar de recursos individuales, como permisos
write-article,read-log, etc. No controla el acceso a artículos o registros específicos. - RBAC (Control de Acceso Basado en Roles)
- RBAC con roles de recursos: los usuarios y recursos pueden tener roles (o grupos) simultáneamente.
- RBAC con dominios/inquilinos: los usuarios pueden tener diferentes conjuntos de roles para diferentes dominios/inquilinos.
- ABAC (Control de Acceso Basado en Atributos): soporta el uso de sintaxis como
resource.Ownerpara obtener atributos de elementos. - RESTful: soporta rutas como
/res/*,/res/:idy métodos HTTP comoGET,POST,PUT,DELETE. - Prioridad de denegación: soporta autorización de permitir y denegar, la denegación tiene prioridad sobre el permiso.
- Prioridad: las reglas de política se determinan en orden secuencial, similar a las reglas de firewall.
Principio de funcionamiento
En Casbin, los modelos de control de acceso se abstraen como archivos de configuración basados en PERM, donde PERM significa Policy (política), Effect (efecto), Request (solicitud), Matcher (coincidencia). Al modificar el mecanismo de autorización en el proyecto, solo es necesario modificar el archivo de configuración. Un archivo de modelo normal tiene el siguiente contenido:
[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.actEste es el modelo de control de acceso ACL más simple.
Política
En el archivo de configuración, la sección de definición de política es
[policy_definition]
p = sub, obj, actp se refiere a policy, no puede ser reemplazado por otros caracteres, sub se refiere a subject, que es el sujeto de la política, obj es object, que es el objeto de la política, act es action, que se refiere a la acción.
p = sub, obj, actTambién puede haber un cuarto campo eft, si se omite, eft es allow por defecto.
p = sub, obj, act, eftEsta línea define cómo se debe escribir la política, no es la definición de política específica. A continuación se muestra un ejemplo de política específica
p, jojo, cake, eatp representa que esta es una definición de regla de política, jojo es el sujeto de la política, cake es el objeto de la política, eat es la acción, el significado completo es que el sujeto jojo puede realizar la acción eat sobre el objeto cake. Las reglas de política específicas no aparecerán en el archivo de modelo, habrá un archivo de política o base de datos dedicada para almacenar las políticas.
Solicitud
En el archivo de configuración, la sección de definición de solicitud es
[request_definition]
r = sub, obj, actr se refiere a request, no puede ser reemplazado por otros caracteres, sub es subject, que se refiere al sujeto de la solicitud, obj es object, que se refiere al objeto de la solicitud, act es action, que se refiere a la acción de la solicitud. En general, la definición de solicitud y la definición de política tienen los mismos nombres de campo. La parte de solicitud no es responsabilidad de casbin, esto lo decide el desarrollador qué es el sujeto de la solicitud y qué es el objeto de la solicitud, casbin solo necesita realizar el control de acceso según los campos transmitidos.
Coincidencia
En el archivo de configuración, la sección de definición de coincidencia es
[matchers]
m = r.sub == p.sub && r.obj == p.obj && r.act == p.actm se refiere a matcher, no se pueden usar otros caracteres, seguido de las reglas de coincidencia correspondientes, lo anterior es una expresión booleana simple, que significa que si todos los campos de la solicitud transmitida coinciden con todos los campos de la regla de política, entonces coincide, por supuesto, también puede ser un comodín o una expresión regular más expresiva.
Además, matcher soporta la sintaxis in, por ejemplo
[matchers]
m = r.sub in ("root","admin")También puede ser
[matchers]
m = r.sub.Name in (r.obj.Admins)e.Enforce(Sub{Name: "alice"}, Obj{Name: "a book", Admins: []interface{}{"alice", "bob"}})Al realizar la coincidencia, Casbin no realiza verificación de tipos, sino que lo trata como interface para verificar si es igual con ==.
Efecto
La sección de definición de efecto realiza nuevamente una combinación lógica de los resultados de coincidencia, en el archivo de configuración, la sección de definición de efecto es
[policy_effect]
e = some(where (p.eft == allow))e se refiere a effect, no se pueden usar otros caracteres. El cuantificador some determina si existe una regla de política que satisfaga el coincidente. El cuantificador any determina si todas las reglas de política satisfacen el coincidente.
some(where (p.eft == allow))Esta regla significa que si hay un resultado allow en los resultados de coincidencia, entonces el resultado final es allow.
e = !some(where (p.eft == deny))Esta regla significa que si no hay resultados deny en los resultados de coincidencia, entonces el resultado final es allow.
e = some(where (p.eft == allow)) && !some(where (p.eft == deny))Esta regla significa que en los resultados de coincidencia, si hay uno allow y no existe ningún resultado deny, entonces el resultado final es allow.
Aunque Casbin diseñó la gramática anterior para efectos de política, la ejecución actual solo usa efectos de política codificados. No creen que esta flexibilidad sea muy necesaria. Hasta ahora, debes usar los efectos de política integrados, no puedes personalizarlos, los efectos de política integrados soportados son los siguientes.
| Definición de efecto de política | Significado | Ejemplo |
|---|---|---|
| some(where (p.eft == allow)) | allow-override | ACL, RBAC, etc. |
| !some(where (p.eft == deny)) | deny-override | Denegar reescritura |
| some(where (p.eft == allow)) && !some(where (p.eft == deny)) | allow-and-deny | Permitir y denegar |
| priority(p.eft) || deny | priority | Prioridad |
| subjectPriority(p.eft) | Prioridad basada en roles | Prioridad de sujeto |
TIP
Las cuatro definiciones anteriores pueden definirse múltiples veces, la sintaxis es
type+number, por ejemplor2,p2,e2,m2.Los archivos de modelo pueden tener comentarios, que se comentan con el símbolo
#.
Ejemplo
A continuación se muestra un ejemplo que demuestra el proceso de trabajo del archivo de modelo. Primero, defina un archivo de modelo ACL simple como sigue
[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.actEl archivo de política es el siguiente
p, alice, data1, read
p, bob, data2, writeEl proceso de cómo abstraer el sujeto, objeto y acción lo decide la lógica de negocio, aquí no es importante, así que se omite. A continuación se muestra la forma más simple de mostrar la solicitud transmitida, como sigue
alice, data1, read
bob, data1, read
alice, data2, write
bob, data2, writeEl archivo de política define que alice tiene permiso para realizar la operación read en data1, bob tiene permiso para realizar la operación write en data2, entonces en la solicitud transmitida
alice, data1, readsignifica que alice quiere realizar la operación read en data1,
bob, data1, readsignifica que bob quiere realizar la operación read en data1, lo demás es similar. Entonces el resultado final es
true
false
false
trueEste es un ejemplo ACL más simple, el sitio web oficial de Casbin permite editar y probar ejemplos en línea, vaya a Casbin editor para probar.
RBAC
RBAC (Role-Based-Access-Controll), Control de Acceso Basado en Roles, en comparación con el modelo ACL tendrá un [role_definition] adicional, a continuación se muestra un modelo 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.actDonde la definición de roles es la siguiente
[role_definition]
g = _, _g se refiere a group, no puede ser reemplazado por otros caracteres, soporta la creación de múltiples con la forma type+number, _ es un marcador de posición, indica cuántos parámetros de entrada hay. En general, en Policy, g suele tener el siguiente formato
g, alice, data2_admin
g, mike, data1_admin
g, data1_admin data2_adminalice se refiere al sujeto, data2_admin se refiere al rol, estrictamente hablando, casbin los tratará como cadenas, cómo entender su significado y uso depende del desarrollador.
g, alice, data2_adminsignifica que alice tiene el rol data2_admin
g, mike, data1_adminsignifica que mike tiene el rol data1_admin
g, data1_admin data2_adminsignifica que el rol data1_admin tiene el rol data2_admin, esta es la relación de herencia entre roles.
Modelo de roles de recursos
El modelo de roles de recursos agrega un g2, como definición de roles de recursos, la definición del modelo es la siguiente
[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.actLa definición de ejemplo de Policy es la siguiente
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_groupDonde g2 define el grupo de roles de recursos, asigna recursos a diferentes roles, y al mismo tiempo especifica la relación de usuario entre roles de usuario y roles de recursos.
p, data_group_admin, data_group, writeEsta estrategia define que un usuario con el rol data_group_admin puede realizar operaciones de escritura en recursos con el rol data_group.
Modelo de dominio multiinquilino
[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.actEl modelo de dominio multiinquilino tiene un campo dom adicional en comparación con el modelo RBAC tradicional, utilizado para indicar el dominio al que pertenece el sujeto. El ejemplo de Policy es el siguiente
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, domain2Por ejemplo
p, admin, domain1, data1, readdefine que el sujeto admin que pertenece al dominio domain1 tiene permiso para realizar la operación read en data1
g, alice, admin, domain1define que alice pertenece a domain1 y tiene el rol admin
