跳到主要内容

Casbin适配器

Casbin 通过 adapters 加载和保存策略。enforcer 调用 LoadPolicy() 来加载规则,并在支持时调用 SavePolicy() 来持久化它们。Adapters 在单独的包中实现,以保持核心库的精简。

支持的 adapters​

下面列出了按语言分类的 adapters。要添加第三方 adapter,请开启一个 issue 或 PR。

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
casbin-pgx-adapter SQL @noho-digital ✅ A PostgreSQL adapter for Casbin using the pgx driver.
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
备注
  1. 当你使用 adapter(显式或隐式)调用 casbin.NewEnforcer() 时,策略会自动加载。
  2. 调用 e.LoadPolicy() 以从存储刷新策略。
  3. 如果不支持 Auto-Save,当你修改策略时,adapters 无法自动持久化策略更改。请手动调用 SavePolicy() 以持久化所有规则。

示例​

以下是几个 adapter 的使用示例:

File adapter(内置)​

使用内置的文件 adapter 初始化 enforcer:

import "github.com/casbin/casbin/v3"

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

等效替代方案:

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

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

MySQL adapter​

使用位于 127.0.0.1:3306 的 MySQL 数据库连接初始化 enforcer,用户名为 root,密码为空:

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

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

使用你自己的存储 adapter​

集成自定义 adapter:

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

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

在不同 adapter 之间迁移/转换​

要将策略从 adapter A 迁移到 adapter B:

  1. 将策略从 A 加载到内存
e, _ := NewEnforcer(m, A)

或

e.SetAdapter(A)
e.LoadPolicy()

2.从适配器 A 切换到 B

e.SetAdapter(B)

3.将策略从内存保存到 B

e.SavePolicy()

Load/Save at run-time​

在初始化后重新加载模型和策略或持久化策略更改:

// 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()

AutoSave​

支持自动保存(Auto-Save)功能的适配器可以将单个策略更改直接持久化到存储中,而无需执行完整的保存操作。这与 SavePolicy() 不同,后者会清除存储并重写所有策略,在处理大型策略集时可能会导致性能问题。

当适配器支持自动保存(Auto-Save)时,通过 Enforcer.EnableAutoSave() 来控制此行为。对于兼容的适配器,此选项默认启用。

备注
  1. 自动保存(Auto-Save)是一项可选功能。适配器可以选择实现或不实现该功能。
  2. 只有当 enforcer 的适配器支持时,自动保存(Auto-Save)才能正常工作。
  3. 请查看上方适配器列表中的 AutoSave 列以确定是否支持。

自动保存(Auto-Save)使用示例:

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

// AutoSave is enabled by default when using compatible adapters with enforcers.
a := xormadapter.NewAdapter("mysql", "mysql_username:mysql_password@tcp(127.0.0.1:3306)/")
e := casbin.NewEnforcer("examples/basic_model.conf", a)

// Disable AutoSave.
e.EnableAutoSave(false)

// Policy changes affect only the in-memory enforcer,
// not the storage.
e.AddPolicy(...)
e.RemovePolicy(...)

// Enable AutoSave.
e.EnableAutoSave(true)

// Policy changes now persist to storage
// in addition to updating the in-memory enforcer.
e.AddPolicy(...)
e.RemovePolicy(...)

更多示例:https://github.com/apache/casbin-xorm-adapter/blob/master/adapter_test.go

How to write an adapter​

实现 Adapter 接口,至少包含两个必需方法:LoadPolicy(model model.Model) error 和 SavePolicy(model model.Model) error。

三个可选方法可启用自动保存(Auto-Save)支持。

MethodTypeDescription
LoadPolicy()mandatory从存储中加载所有策略规则
SavePolicy()mandatory将所有策略规则保存到存储
AddPolicy()optional向存储中添加一个策略规则
RemovePolicy()optional从存储中移除一个策略规则
RemoveFilteredPolicy()optional从存储中移除匹配过滤器的策略规则
备注

当适配器不支持自动保存(Auto-Save)时,为这三个可选方法提供空实现。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 enforcers 在调用这些可选方法时会忽略 "not implemented" 错误。

适配器实现要求:

  • 数据结构。至少支持读取六列。
  • 数据库名称。默认为 casbin。
  • 表名称。默认为 casbin_rule。
  • Ptype 列。命名为 ptype(而不是 p_type 或 Ptype)。
  • 表定义:(id int primary key, ptype varchar, v0 varchar, v1 varchar, v2 varchar, v3 varchar, v4 varchar, v5 varchar)。
  • 唯一键索引:基于列 ptype,v0,v1,v2,v3,v4,v5 构建。
  • LoadFilteredPolicy 接受如下结构的过滤器参数:
{
"p": ["", "domain1"],
"g": ["", "", "domain1"]
}

Who is responsible to create the DB?​

按照约定,适配器应在数据库不存在时自动创建一个名为 casbin 的数据库,并将其用于策略存储。参考实现:https://github.com/apache/casbin-xorm-adapter

Update Adapter​

UpdateAdapter 接口扩展了基本的 Adapter 接口,以实现在存储中直接更新策略。与修改现有规则时的删除再添加序列相比,这种方式更高效。

实现 UpdateAdapter 的适配器提供以下方法:

MethodTypeDescription
UpdatePolicy()optional在存储中更新单个策略规则
UpdatePolicies()optional在存储中更新多个策略规则
UpdateFilteredPolicies()optional在存储中更新匹配过滤器的策略规则

示例​

更新适配器用法:

import (
"github.com/casbin/casbin/v3"
"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",
)

如何编写更新适配器​

要实现 UpdateAdapter,请在你的基础 Adapter 实现中添加更新方法:

// 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 {
// Update the policy in storage
// SQL example: 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 {
// Update multiple policies in storage
// Use transactions 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 {
// Find policies matching the filter, then update them
return nil
}
备注

如果不支持 UpdateAdapter,Casbin 会自动回退到组合使用 RemovePolicy() 和 AddPolicy() 操作。

上下文适配器​

ContextAdapter 为 Casbin 适配器提供上下文感知操作。

上下文可实现诸如适配器 API 调用超时控制等功能。

示例​

gormadapter 支持上下文。以下是使用上下文进行超时控制的示例:

ca, _ := NewContextAdapter("mysql", "root:@tcp(127.0.0.1:3306)/", "casbin")
// Set 300s timeout
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)
}

如何编写上下文适配器​

ContextAdapter API 在标准 Adapter API 之上增加了一层上下文处理逻辑。实现标准 Adapter API 后,用上下文处理包装你的逻辑。

参考实现:adapter.go

交易​

Casbin 支持事务。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.
// Errors trigger rollback; otherwise, automatic commit occurs.
err := e.WithTransaction(ctx, func(tx *casbin.Transaction) error {
tx.AddPolicy("alice", "data1", "read")
tx.AddPolicy("alice", "data1", "write")
return nil
})

// Manual transaction handling
tx, _ := e.BeginTransaction(ctx)
tx.AddPolicy("alice", "data1", "write")
if err := tx.Commit(); err != nil {
// handle transaction failure
}

实现 persist/transaction.go 中的 TransactionalAdapter 和 TransactionContext 以添加事务支持。

参考:adapter.go

Comments are powered by giscus and GitHub Discussions. They load from giscus.app and GitHub only after you click the button below.