API Overview
Esta visión general solo muestra cómo usar las APIs de Casbin y no explica cómo se instala Casbin ni cómo funciona. Puedes encontrar esos tutoriales aquí: Instalación de Casbin y Cómo funciona Casbin. Entonces, cuando comiences a leer este tutorial, asumimos que ya has instalado completamente e importado Casbin en tu código.
API de Enforce
Comencemos con las APIs de Enforce de Casbin. Cargaremos un modelo RBAC desde model.conf
y cargaremos políticas desde policy.csv
. Puedes aprender sobre la sintaxis del Modelo aquí, y no lo discutiremos en este tutorial. Suponemos que puedes entender los archivos de configuración que se muestran a continuación:
model.conf
[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
policy.csv
p, admin, data1, read
p, admin, data1, write
p, admin, data2, read
p, admin, data2, write
p, alice, data1, read
p, bob, data2, write
g, amber, admin
g, abc, admin
Después de leer los archivos de configuración, por favor lee el siguiente código.
// Load information from files.
enforcer, err := casbin.NewEnforcer("./example/model.conf", "./example/policy.csv")
if err != nil {
log.Fatalf("Error, detail: %s", err)
}
ok, err := enforcer.Enforce("alice", "data1", "read")
Este código carga el modelo de control de acceso y las políticas desde archivos locales. La función casbin.NewEnforcer()
devolverá un enforcer. Reconocerá sus dos parámetros como rutas de archivos y cargará los archivos desde allí. Los errores ocurridos en el proceso se almacenan en la variable err
. Este código utiliza el adaptador predeterminado para cargar el modelo y las políticas, y por supuesto, puedes lograr el mismo resultado utilizando un adaptador de terceros.
El código ok, err := enforcer.Enforce("alice", "data1", "read")
se utiliza para confirmar permisos de acceso. Si Alice puede acceder a data1 con la operación de lectura, el valor devuelto de ok
será true
; de lo contrario, será false
. En este ejemplo, el valor de ok
es true
.
EnforceEx API
A veces puedes preguntarte qué política permitió la solicitud, por eso hemos preparado la función EnforceEx()
. Puedes usarla así:
ok, reason, err := enforcer.EnforceEx("amber", "data1", "read")
fmt.Println(ok, reason) // true [admin data1 read]
La función EnforceEx()
devolverá la cadena de política exacta en el valor de retorno reason
. En este ejemplo, amber
tiene un rol de admin
, por lo que la política p, admin, data1, read
permitió que esta solicitud fuera true
. La salida de este código está en el comentario.
Casbin ha proporcionado muchas APIs similares a esta. Estas APIs añaden algunas funciones extras a las básicas. Incluyen:
ok, err := enforcer.EnforceWithMatcher(matcher, request)
Esta función utiliza un matcher.
ok, reason, err := enforcer.EnforceExWithMatcher(matcher, request)
Esta es una combinación de
EnforceWithMatcher()
yEnforceEx()
.boolArray, err := enforcer.BatchEnforce(requests)
Esta función permite una lista de trabajos y devuelve un array.
Este es un caso de uso simple de Casbin. Puedes usar Casbin para iniciar un servidor de autorización utilizando estas APIs. Te mostraremos algunos otros tipos de APIs en los siguientes párrafos.
API de Gestión
API de Obtención
Estas APIs se utilizan para recuperar objetos específicos en políticas. En este ejemplo, estamos cargando un enforcer y recuperando algo de él.
Por favor, echa un vistazo al siguiente código:
enforcer, err := casbin.NewEnforcer("./example/model.conf", "./example/policy.csv")
if err != nil {
fmt.Printf("Error, details: %s\n", err)
}
allSubjects := enforcer.GetAllSubjects()
fmt.Println(allSubjects)
Similar al ejemplo anterior, las primeras cuatro líneas se utilizan para cargar la información necesaria desde archivos locales. No discutiremos eso aquí más a fondo.
El código allSubjects := enforcer.GetAllSubjects()
recupera todos los sujetos en el archivo de política y los devuelve como un array. Luego imprimimos ese array.
Típicamente, la salida del código debería ser:
[admin alice bob]
También puedes cambiar la función GetAllSubjects()
por GetAllNamedSubjects()
para obtener la lista de sujetos que aparecen en la política nombrada actual.
De manera similar, hemos preparado funciones GetAll
para Objects, Actions, Roles
. Para acceder a estas funciones, simplemente necesitas reemplazar la palabra Subject
en el nombre de la función con la categoría deseada.
Además, hay más getters disponibles para políticas. El método de llamada y los valores de retorno son similares a los mencionados anteriormente.
policy = e.GetPolicy()
recupera todas las reglas de autorización en la política.filteredPolicy := e.GetFilteredPolicy(0, "alice")
recupera todas las reglas de autorización en la política con filtros de campo especificados.namedPolicy := e.GetNamedPolicy("p")
recupera todas las reglas de autorización en la política nombrada.filteredNamedPolicy = e.GetFilteredNamedPolicy("p", 0, "bob")
recupera todas las reglas de autorización en la política nombrada con filtros de campo especificados.groupingPolicy := e.GetGroupingPolicy()
recupera todas las reglas de herencia de roles en la política.filteredGroupingPolicy := e.GetFilteredGroupingPolicy(0, "alice")
recupera todas las reglas de herencia de roles en la política con filtros de campo especificados.namedGroupingPolicy := e.GetNamedGroupingPolicy("g")
recupera todas las reglas de herencia de roles en la política.namedGroupingPolicy := e.GetFilteredNamedGroupingPolicy("g", 0, "alice")
recupera todas las reglas de herencia de roles en la política con filtros de campo especificados.
Add, Delete, Update API
Casbin ofrece una variedad de APIs para agregar, eliminar o modificar políticas dinámicamente en tiempo de ejecución.
El siguiente código demuestra cómo agregar, eliminar y actualizar políticas, así como cómo verificar si una política existe:
// load information from files
enforcer, err := casbin.NewEnforcer("./example/model.conf", "./example/policy.csv")
if err != nil {
fmt.Printf("Error, details: %s\n", err)
}
// add a policy and use HasPolicy() to confirm
enforcer.AddPolicy("added_user", "data1", "read")
hasPolicy := enforcer.HasPolicy("added_user", "data1", "read")
fmt.Println(hasPolicy) // true, the policy was added successfully
// remove a policy and use HasPolicy() to confirm
enforcer.RemovePolicy("alice", "data1", "read")
hasPolicy = enforcer.HasPolicy("alice", "data1", "read")
fmt.Println(hasPolicy) // false, the policy was removed successfully
// update a policy and use HasPolicy() to confirm
enforcer.UpdatePolicy([]string{"added_user", "data1", "read"}, []string{"added_user", "data1", "write"})
hasPolicy = enforcer.HasPolicy("added_user", "data1", "read")
fmt.Println(hasPolicy) // false, the original policy has expired
hasPolicy = enforcer.HasPolicy("added_user", "data1", "write")
fmt.Println(hasPolicy) // true, the new policy is in effect
Al usar estas APIs, puedes editar tus políticas dinámicamente. De manera similar, hemos proporcionado APIs similares para FilteredPolicy, NamedPolicy, FilteredNamedPolicy, GroupingPolicy, NamedGroupingPolicy, FilteredGroupingPolicy, FilteredNamedGroupingPolicy
. Para usarlas, simplemente reemplaza la palabra Policy
en el nombre de la función con la categoría apropiada.
Además, al cambiar los parámetros a arreglos, puedes realizar edición por lotes de tus políticas.
Por ejemplo, considera funciones como esta:
enforcer.UpdatePolicy([]string{"eve", "data3", "read"}, []string{"eve", "data3", "write"})
Si cambiamos Policy
por Policies
y modificamos los parámetros de la siguiente manera:
enforcer.UpdatePolicies([][]string{{"eve", "data3", "read"}, {"jack", "data3", "read"}}, [][]string{{"eve", "data3", "write"}, {"jack", "data3", "write"}})
entonces podemos realizar edición por lotes de estas políticas.
Las mismas operaciones también se pueden aplicar a GroupingPolicy, NamedGroupingPolicy
.
AddEx API
Casbin ofrece la serie de APIs AddEx para ayudar a los usuarios a agregar reglas en lotes.
AddPoliciesEx(rules [][]string) (bool, error)
AddNamedPoliciesEx(ptype string, rules [][]string) (bool, error)
AddGroupingPoliciesEx(rules [][]string) (bool, error)
AddNamedGroupingPoliciesEx(ptype string, rules [][]string) (bool, error)
SelfAddPoliciesEx(sec string, ptype string, rules [][]string) (bool, error)
La diferencia entre estos métodos y los métodos sin el sufijo Ex es que si una de las reglas ya existe, continuarán comprobando la siguiente regla en lugar de devolver falso inmediatamente.
Por ejemplo, comparemos AddPolicies
y AddPoliciesEx
.
Puedes ejecutar y observar el siguiente código copiándolo en la prueba bajo casbin.
func TestDemo(t *testing.T) {
e, err := NewEnforcer("examples/basic_model.conf", "examples/basic_policy.csv")
if err != nil {
fmt.Printf("Error, details: %s\n", err)
}
e.ClearPolicy()
e.AddPolicy("user1", "data1", "read")
fmt.Println(e.GetPolicy())
testGetPolicy(t, e, [][]string{{"user1", "data1", "read"}})
// policy {"user1", "data1", "read"} now exists
// Use AddPolicies to add rules in batches
ok, _ := e.AddPolicies([][]string{{"user1", "data1", "read"}, {"user2", "data2", "read"}})
fmt.Println(e.GetPolicy())
// {"user2", "data2", "read"} failed to add because {"user1", "data1", "read"} already exists
// AddPolicies returns false and no other policies are checked, even though they may not exist in the existing ruleset
// ok == false
fmt.Println(ok)
testGetPolicy(t, e, [][]string{{"user1", "data1", "read"}})
// Use AddPoliciesEx to add rules in batches
ok, _ = e.AddPoliciesEx([][]string{{"user1", "data1", "read"}, {"user2", "data2", "read"}})
fmt.Println(e.GetPolicy())
// {"user2", "data2", "read"} is added successfully
// because AddPoliciesEx automatically filters the existing {"user1", "data1", "read"}
// ok == true
fmt.Println(ok)
testGetPolicy(t, e, [][]string{{"user1", "data1", "read"}, {"user2", "data2", "read"}})
}
RBAC API
Casbin ofrece algunas APIs para que modifiques el modelo RBAC y las políticas. Si estás familiarizado con RBAC, puedes usar fácilmente estas APIs.
Aquí, solo te mostramos cómo usar las APIs RBAC de Casbin y no hablaremos sobre RBAC en sí. Puedes obtener más detalles aquí.
Usamos el siguiente código para cargar el modelo y las políticas, justo como antes.
enforcer, err := casbin.NewEnforcer("./example/model.conf", "./example/policy.csv")
if err != nil {
fmt.Printf("Error, details: %s\n", err)
}
Entonces, podemos usar una instancia del Enforcer enforcer
para acceder a estas APIs.
roles, err := enforcer.GetRolesForUser("amber")
fmt.Println(roles) // [admin]
users, err := enforcer.GetUsersForRole("admin")
fmt.Println(users) // [amber abc]
GetRolesForUser()
devuelve un arreglo que contiene todos los roles que tiene amber. En este ejemplo, amber solo tiene un rol, que es admin, por lo que el arreglo roles
es [admin]
. De manera similar, puedes usar GetUsersForRole()
para obtener los usuarios que pertenecen a un rol. El valor de retorno de esta función también es un arreglo.
enforcer.HasRoleForUser("amber", "admin") // true
Puedes usar HasRoleForUser()
para confirmar si el usuario pertenece al rol. En este ejemplo, amber es miembro de admin, por lo que el valor de retorno de la función es true
.
fmt.Println(enforcer.Enforce("bob", "data2", "write")) // true
enforcer.DeletePermission("data2", "write")
fmt.Println(enforcer.Enforce("bob", "data2", "write")) // false
Puedes usar DeletePermission()
para eliminar un permiso.
fmt.Println(enforcer.Enforce("alice", "data1", "read")) // true
enforcer.DeletePermissionForUser("alice", "data1", "read")
fmt.Println(enforcer.Enforce("alice", "data1", "read")) // false
Y usar DeletePermissionForUser()
para eliminar un permiso para un usuario.
Casbin tiene muchas APIs como esta. Sus métodos de llamada y valores de retorno tienen el mismo estilo que las APIs anteriores. Puedes encontrar estas APIs en los próximos documentos.