Ir al contenido principal

Adapters

En Casbin, el almacenamiento de políticas se implementa como un adaptador (también conocido como middleware para Casbin). Un usuario de Casbin puede usar un adaptador para cargar reglas de políticas desde un almacenamiento (también conocido como LoadPolicy()), o guardar reglas de políticas en él (también conocido como SavePolicy()). Para mantenerse ligero, no incluimos el código del adaptador en la biblioteca principal.

Adaptadores compatibles

Se proporciona una lista completa de adaptadores de Casbin a continuación. Cualquier contribución de terceros sobre un nuevo adaptador es bienvenida, por favor infórmenos y lo incluiremos en esta lista:

Adapter Type Author AutoSave Description
File Adapter (built-in) File Casbin For .CSV (Comma-Separated Values) files
Filtered File Adapter (built-in) File @faceless-saint For .CSV (Comma-Separated Values) files with policy subset loading support
SQL Adapter SQL @Blank-Xu MySQL, PostgreSQL, SQL Server, SQLite3 are supported in master branch and Oracle is supported in oracle branch by database/sql
Xorm Adapter ORM Casbin MySQL, PostgreSQL, TiDB, SQLite, SQL Server, Oracle are supported by Xorm
GORM Adapter ORM Casbin MySQL, PostgreSQL, Sqlite3, SQL Server are supported by GORM
GORM Adapter Ex ORM Casbin MySQL, PostgreSQL, Sqlite3, SQL Server are supported by GORM
Ent Adapter ORM Casbin MySQL, MariaDB, PostgreSQL, SQLite, Gremlin-based graph databases are supported by ent ORM
Beego ORM Adapter ORM Casbin MySQL, PostgreSQL, Sqlite3 are supported by Beego ORM
SQLX Adapter ORM @memwey MySQL, PostgreSQL, SQLite, Oracle are supported by SQLX
Sqlx Adapter ORM @Blank-Xu MySQL, PostgreSQL, SQL Server, SQLite3 are supported in master branch and Oracle is supported in oracle branch by sqlx
GF ORM Adapter ORM @vance-liu MySQL, SQLite, PostgreSQL, Oracle, SQL Server are supported by GoFrame ORM
GoFrame ORM Adapter ORM @kotlin2018 MySQL, SQLite, PostgreSQL, Oracle, SQL Server are supported by GoFrame ORM
gf-adapter ORM @zcyc MySQL, SQLite, PostgreSQL, Oracle, SQL Server are supported by GoFrame ORM
Gdb Adapter ORM @jxo-me MySQL, SQLite, PostgreSQL, Oracle, SQL Server are supported by GoFrame ORM
GoFrame V2 Adapter ORM @hailaz MySQL, SQLite, PostgreSQL, Oracle, SQL Server are supported by GoFrame ORM
Bun Adapter ORM @JunNishimura MySQL, SQLite, PostgreSQL, SQL Server are supported by Bun ORM
Filtered PostgreSQL Adapter SQL Casbin For PostgreSQL
Filtered pgx Adapter SQL @pckhoi PostgreSQL is supported by pgx
Pgx Adapter SQL @gtoxlili PostgreSQL is supported by pgx, supports customizable column count
PostgreSQL Adapter SQL @cychiuae For PostgreSQL
RQLite Adapter SQL EDOMO Systems For RQLite
MongoDB Adapter NoSQL Casbin For MongoDB based on MongoDB Go Driver
RethinkDB Adapter NoSQL @adityapandey9 For RethinkDB
Cassandra Adapter NoSQL Casbin For Apache Cassandra DB
DynamoDB Adapter NoSQL HOOQ For Amazon DynamoDB
Dynacasbin NoSQL NewbMiao For Amazon DynamoDB
ArangoDB Adapter NoSQL @adamwasila For ArangoDB
Amazon S3 Adapter Cloud Soluto For Minio and Amazon S3
Go CDK Adapter Cloud @bartventer Adapter based on Go Cloud Dev Kit that supports: Amazon DynamoDB, Azure CosmosDB, GCP Firestore, MongoDB, In-Memory
Azure Cosmos DB Adapter Cloud @spacycoder For Microsoft Azure Cosmos DB
GCP Firestore Adapter Cloud @reedom For Google Cloud Platform Firestore
GCP Cloud Storage Adapter Cloud qurami For Google Cloud Platform Cloud Storage
GCP Cloud Spanner Adapter Cloud @flowerinthenight For Google Cloud Platform Cloud Spanner
Consul Adapter KV store @ankitm123 For HashiCorp Consul
Redis Adapter (Redigo) KV store Casbin For Redis
Redis Adapter (go-redis) KV store @mlsen For Redis
Etcd Adapter KV store @sebastianliu For etcd
BoltDB Adapter KV store @speza For Bolt
Bolt Adapter KV store @wirepair For Bolt
BadgerDB Adapter KV store @inits For BadgerDB
Protobuf Adapter Stream Casbin For Google Protocol Buffers
JSON Adapter String Casbin For JSON
String Adapter String @qiangmzsx For String
HTTP File Adapter HTTP @h4ckedneko For http.FileSystem
FileSystem Adapter File @naucon For fs.FS and embed.FS
NATS JetStream Adapter KV store grepplabs For NATS JetStream
Kubernetes Adapter Cloud grepplabs For Kubernetes
nota
  1. Si se llama a casbin.NewEnforcer() con un adaptador explícito o implícito, la política se cargará automáticamente.
  2. Puede llamar a e.LoadPolicy() para recargar las reglas de políticas desde el almacenamiento.
  3. Si el adaptador no admite la función de Auto-Guardado, las reglas de políticas no se pueden guardar automáticamente de vuelta en el almacenamiento cuando se agregan o eliminan políticas. Tiene que llamar a SavePolicy() manualmente para guardar todas las reglas de políticas.

Ejemplos

Aquí proporcionamos varios ejemplos:

Adaptador de archivo (integrado)

A continuación se muestra cómo inicializar un enforcer desde el adaptador de archivo integrado:

import "github.com/casbin/casbin"

e := casbin.NewEnforcer("examples/basic_model.conf", "examples/basic_policy.csv")

Esto es lo mismo que:

import (
"github.com/casbin/casbin"
"github.com/casbin/casbin/file-adapter"
)

a := fileadapter.NewAdapter("examples/basic_policy.csv")
e := casbin.NewEnforcer("examples/basic_model.conf", a)

Adaptador MySQL

A continuación se muestra cómo inicializar un enforcer desde una base de datos MySQL. se conecta a una base de datos MySQL en 127.0.0.1:3306 con root y contraseña en blanco.

import (
"github.com/casbin/casbin"
"github.com/casbin/mysql-adapter"
)

a := mysqladapter.NewAdapter("mysql", "root:@tcp(127.0.0.1:3306)/")
e := casbin.NewEnforcer("examples/basic_model.conf", a)

Utilice su propio adaptador de almacenamiento

Puede usar su propio adaptador como se muestra a continuación:

import (
"github.com/casbin/casbin"
"github.com/your-username/your-repo"
)

a := yourpackage.NewAdapter(params)
e := casbin.NewEnforcer("examples/basic_model.conf", a)

Migrar/Convertir entre diferentes adaptadores

Si desea convertir el adaptador de A a B, puede hacerlo de la siguiente manera:

1.Cargar la política de A a la memoria

e, _ := NewEnforcer(m, A)

o

e.SetAdapter(A)
e.LoadPolicy()

2.convertir su adaptador de A a B

e.SetAdapter(B)

3.Guardar la política de la memoria a B

e.SavePolicy()

Cargar/Guardar en tiempo de ejecución

También puede querer recargar el modelo, recargar la política o guardar la política después de la inicialización:

// Reload the model from the model CONF file.
e.LoadModel()

// Reload the policy from file/database.
e.LoadPolicy()

// Save the current policy (usually after changed with Casbin API) back to file/database.
e.SavePolicy()

AutoGuardado

Hay una función llamada Auto-Guardado para adaptadores. Cuando un adaptador admite Auto-Guardado, significa que puede admitir agregar una regla de política individual al almacenamiento, o eliminar una regla de política individual del almacenamiento. Esto es diferente de SavePolicy(), porque este último eliminará todas las reglas de políticas en el almacenamiento y guardará todas las reglas de políticas del enforcer de Casbin en el almacenamiento. Por lo tanto, puede sufrir problemas de rendimiento cuando el número de reglas de políticas es grande.

Cuando el adaptador admite Auto-Guardado, puede cambiar esta opción a través de la función Enforcer.EnableAutoSave(). La opción está habilitada por defecto (si el adaptador la admite).

nota
  1. La función de Auto-Guardado es opcional. Un adaptador puede elegir implementarlo o no.
  2. Auto-Guardado solo funciona para un enforcer de Casbin cuando el adaptador que utiliza el enforcer lo admite.
  3. Vea la columna AutoSave en la lista de adaptadores anterior para ver si un adaptador admite Auto-Guardado.

Aquí hay un ejemplo de cómo usar Auto-Guardado:

import (
"github.com/casbin/casbin"
"github.com/casbin/xorm-adapter"
_ "github.com/go-sql-driver/mysql"
)

// By default, the AutoSave option is enabled for an enforcer.
a := xormadapter.NewAdapter("mysql", "mysql_username:mysql_password@tcp(127.0.0.1:3306)/")
e := casbin.NewEnforcer("examples/basic_model.conf", a)

// Disable the AutoSave option.
e.EnableAutoSave(false)

// Because AutoSave is disabled, the policy change only affects the policy in Casbin enforcer,
// it doesn't affect the policy in the storage.
e.AddPolicy(...)
e.RemovePolicy(...)

// Enable the AutoSave option.
e.EnableAutoSave(true)

// Because AutoSave is enabled, the policy change not only affects the policy in Casbin enforcer,
// but also affects the policy in the storage.
e.AddPolicy(...)
e.RemovePolicy(...)

Para más ejemplos, por favor vea: https://github.com/casbin/xorm-adapter/blob/master/adapter_test.go

Cómo escribir un adaptador

Todos los adaptadores deben implementar la interfaz Adapter proporcionando al menos dos métodos obligatorios:LoadPolicy(model model.Model) error y SavePolicy(model model.Model) error.

Las otras tres funciones son opcionales. Deben implementarse si el adaptador admite la función de Auto-Guardado.

MétodoTipoDescripción
LoadPolicy()obligatorioCargar todas las reglas de política desde el almacenamiento
SavePolicy()obligatorioGuardar todas las reglas de política en el almacenamiento
AddPolicy()opcionalAñadir una regla de política al almacenamiento
RemovePolicy()opcionalEliminar una regla de política del almacenamiento
RemoveFilteredPolicy()opcionalEliminar las reglas de política que coincidan con el filtro del almacenamiento
nota

Si un adaptador no soporta 'Auto-Save', debería proporcionar una implementación vacía para las tres funciones opcionales. Aquí hay un ejemplo para Golang:

// AddPolicy adds a policy rule to the storage.
func (a *Adapter) AddPolicy(sec string, ptype string, rule []string) error {
return errors.New("not implemented")
}

// RemovePolicy removes a policy rule from the storage.
func (a *Adapter) RemovePolicy(sec string, ptype string, rule []string) error {
return errors.New("not implemented")
}

// RemoveFilteredPolicy removes policy rules that match the filter from the storage.
func (a *Adapter) RemoveFilteredPolicy(sec string, ptype string, fieldIndex int, fieldValues ...string) error {
return errors.New("not implemented")
}

Casbin enforcer ignorará el error de 'not implemented' cuando llame a estas tres funciones opcionales.

Hay detalles sobre cómo escribir un adaptador.

  • Estructura de Datos. El adaptador debería soportar la lectura de al menos seis columnas.
  • Nombre de la Base de Datos. El nombre predeterminado de la base de datos debería ser 'casbin'.
  • Nombre de la Tabla. El nombre predeterminado de la tabla debería ser 'casbin_rule'.
  • Columna Ptype. El nombre de esta columna debería ser 'ptype' en lugar de 'p_type' o 'Ptype'.
  • La definición de la tabla debería ser '(id int primary key, ptype varchar, v0 varchar, v1 varchar, v2 varchar, v3 varchar, v4 varchar, v5 varchar)'.
  • El índice de clave única debería construirse en las columnas 'ptype,v0,v1,v2,v3,v4,v5'.
  • 'LoadFilteredPolicy' requiere un 'filter' como parámetro. El filtro debería ser algo así.
{
"p": ["", "domain1"],
"g": ["", "", "domain1"]
}

¿Quién es responsable de crear la BD?

Como convención, el adaptador debería poder crear automáticamente una base de datos llamada 'casbin' si no existe y usarla para el almacenamiento de políticas. Por favor, use el adaptador Xorm como una implementación de referencia: https://github.com/casbin/xorm-adapter

Update Adapter

The UpdateAdapter interface extends the basic Adapter interface to support updating policies directly in the storage. This is more efficient than removing and re-adding policies when you need to modify existing rules.

An adapter that implements the UpdateAdapter interface should provide the following methods:

MethodTypeDescription
UpdatePolicy()optionalUpdate a single policy rule in the storage
UpdatePolicies()optionalUpdate multiple policy rules in the storage
UpdateFilteredPolicies()optionalUpdate policy rules that match the filter in the storage

Ejemplo

Here's an example of using the update adapter methods:

import (
"github.com/casbin/casbin/v2"
"github.com/casbin/gorm-adapter/v3"
)

a, _ := gormadapter.NewAdapter("mysql", "root:@tcp(127.0.0.1:3306)/")
e, _ := casbin.NewEnforcer("examples/rbac_model.conf", a)

// Update a single policy
// Change: p, alice, data1, read -> p, alice, data1, write
e.UpdatePolicy(
[]string{"alice", "data1", "read"},
[]string{"alice", "data1", "write"},
)

// Update multiple policies at once
e.UpdatePolicies(
[][]string{{"alice", "data1", "write"}, {"bob", "data2", "read"}},
[][]string{{"alice", "data1", "read"}, {"bob", "data2", "write"}},
)

// Update all policies matching a filter
e.UpdateFilteredPolicies(
[][]string{{"alice", "data1", "write"}},
0,
"alice", "data1", "read",
)

How to write an update adapter

To implement the UpdateAdapter interface, your adapter needs to implement the update methods in addition to the basic Adapter interface:

// UpdatePolicy updates a policy rule from storage.
// This is part of the UpdateAdapter interface.
func (a *Adapter) UpdatePolicy(sec string, ptype string, oldRule, newRule []string) error {
// Implementation to update the policy in storage
// For example, in SQL: UPDATE casbin_rule SET v0=?, v1=?, v2=? WHERE ptype=? AND v0=? AND v1=? AND v2=?
return nil
}

// UpdatePolicies updates multiple policy rules in the storage.
// This is part of the UpdateAdapter interface.
func (a *Adapter) UpdatePolicies(sec string, ptype string, oldRules, newRules [][]string) error {
// Implementation to update multiple policies in storage
// This should be done in a transaction for consistency
return nil
}

// UpdateFilteredPolicies updates policy rules that match the filter from the storage.
// This is part of the UpdateAdapter interface.
func (a *Adapter) UpdateFilteredPolicies(sec string, ptype string, newRules [][]string, fieldIndex int, fieldValues ...string) error {
// Implementation to update filtered policies in storage
// First find policies matching the filter, then update them
return nil
}
nota

If an adapter doesn't support the UpdateAdapter interface, Casbin will automatically fall back to using the combination of RemovePolicy() and AddPolicy() operations.

Context Adapter

ContextAdapter proporciona una interfaz consciente del contexto para los adaptadores de Casbin.

A través del contexto, puedes implementar características como el control de tiempo de espera para la API del Adaptador

Example

gormadapter soporta adaptador con contexto, lo siguiente es un control de tiempo de espera implementado usando contexto

ca, _ := NewContextAdapter("mysql", "root:@tcp(127.0.0.1:3306)/", "casbin")
// Limited time 300s
ctx, cancel := context.WithTimeout(context.Background(), 300*time.Microsecond)
defer cancel()

err := ca.AddPolicyCtx(ctx, "p", "p", []string{"alice", "data1", "read"})
if err != nil {
panic(err)
}

Cómo escribir un adaptador de contexto

La API de 'ContextAdapter' solo tiene una capa extra de procesamiento de contexto que la API de 'Adapter' ordinaria, y sobre la base de implementar la API de Adapter ordinaria, puedes encapsular tu propia lógica de procesamiento para el contexto

A simple reference to the gormadapter: adapter.go

Transaction

Casbin now supports Transactions. Here's an example about how to use Transaction in gormadapter:

db, _ := gorm.Open(...)
adapter, _ := gormadapter.NewTransactionalAdapterByDB(db)
e, _ := casbin.NewTransactionalEnforcer("examples/rbac_model.conf", adapter)

ctx := context.Background()

// WithTransaction executes a function within a transaction.
// If the function returns an error, the transaction is rolled back.
// Otherwise, it's committed automatically.
err := e.WithTransaction(ctx, func(tx *casbin.Transaction) error {
tx.AddPolicy("alice", "data1", "read")
tx.AddPolicy("alice", "data1", "write")
return nil
})

// If you wish to manually handle the transaction
tx, _ := e.BeginTransaction(ctx)
tx.AddPolicy("alice", "data1", "write")
if err := tx.Commit(); err != nil {
// handle if transaction failed
}

To add this capability to your adapter, you need to implement TransactionalAdapter and TransactionContext in persist/transaction.go.

Code reference to the gormadapter: adapter.go