跳转至主要内容

适配器

在Casbin中,策略存储作为adapter(Casbin的中间件) 实现。 Casbin用户可以使用adapter从存储中加载策略规则 (aka LoadPolicy()) 或者将策略规则保存到其中 (aka SavePolicy())。 为了保持代码轻量级,我们没有把adapter代码放在主库中。

目前支持的适配器列表

Casbin的适配器完整列表如下。 我们欢迎任何第三方对adapter进行新的贡献,如果有请通知我们,我们将把它放在这个列表中:)

适配器类型作者自动保存描述
File Adapter (内置)FileCasbinFor .CSV (Comma-Separated Values) files
Filtered File Adapter (内置)FileFile对于 CSV (逗号分隔的值) 个带策略子集加载支持的文件
SQL AdapterSQL@Blank-XuMySQL,PostgreSQL,SQL Server和SQLite3在 master分支中受到database/sql的支持,Oacle在 oracle分支中也受到database/sql的支持
Xorm AdapterORMCasbin通过 Xorm实现,支持MySQL, PostgreSQL, Sqlite3, SQL Server等多种存储引擎的adapter
Gorm AdapterORMCasbin通过 Gorm实现,支持MySQL, PostgreSQL, Sqlite3, SQL Server等多种存储引擎的adapter
Ent AdapterORMCasbinMySQL, MariaDB, PostgreSQL, SQLite, 基于Gremlin的图数据库由 [ent ORM](https://entgo. io/) 支持。
Beego ORM AdapterORMCasbinMySQL, PostgreSQL, Sqlite3 由 Beego ORM 支持
SQLX AdapterORM@memweyMySQL, PostgreSQL, SQLite, Oracle 由 SQLX 支持
Sqlx AdapterSQL@Blank-XuMySQL, PostgreSQL, SQL Server, SQLite3 由 master 分支支持,Oracle由oracle 分支受到sqlx的支持
GF ORM AdapterORM@vance-liuMySQL, SQLite, PostgreSQL, Oracle, SQL Server 受到 GoFrame ORM 的支持
GoFrame ORM AdapterORM@kotlin2018MySQL, SQLite, PostgreSQL, Oracle, SQL Server 受到 GoFrame ORM 的支持
Filtered PostgreSQL AdapterSQLCasbin用于PostgreSQL
Filtered pgx AdapterSQL@pckhoi使用 pgx 支持PostgreSQL
PostgreSQL AdapterSQL@cychiuae用于PostgreSQL
RQLite AdapterSQLEDOMO Systems用于 RQLite
MongoDB AdapterNoSQLCasbin基于 MongoDB Go Driver 用于 MongoDB
RethinkDB AdapterNoSQL@adityapandey9用于RethinkDB
Cassandra AdapterNoSQLCasbin用于Apache Cassandra DB
DynamoDB AdapterNoSQLHOOQ用于Amazon DynamoDB
DynacasbinNoSQLNewbMiao用于Amazon DynamoDB
ArangoDB AdapterNoSQL@adamwasila用于ArangoDB
Amazon S3 AdapterSoluto用于MinioAmazon S3
Azure Cosmos DB Adapter@spacycoder用于 Microsoft Azure Cosmos DB
GCP Firestore Adapter@reedom用于 Google Cloud Platform Firestore
GCP Cloud Storage Adapterqurami用于 Google Cloud Platform Cloud Storage
GCP Cloud Storage Adapter@flowerinthenight用于Google Cloud Platform Cloud Spanner
Consul AdapterKV store@ankitm123用于 HashiCorp Consul
Redis 适配器 (Redigo)KV storeCasbin用于 Redis
Redis Adapter (go-redis)KV store@mlsen用于 Redis
Etcd 适配器KV store@sebastianliu用于 etcd
BoltDB AdapterKV store@speza用于 Bolt
Bolt AdapterKV store@wirepair用于 Bolt
BadgerDB AdapterKV store@inits用于 BadgerDB
Protobuf AdapterStreamCasbin用于 Google Protocol Buffers
JSON AdapterStringCasbin用于 JSON
String AdapterString@qiangmzsx用于 String
HTTP File AdapterHTTP@h4ckedneko用于 http.FileSystem
FileSystem AdapterFile@naucon用于fs.FSembed.FS
备注
  1. 如果使用显式或隐式adapter调用casbin.NewEnforcer(),策略将自动加载。
  2. 可以调用e.LoadPolicy() 来从存储中重新加载策略规则。
  3. 如果adapter不支持Auto-Save特性,则在添加或删除策略时不能将策略规则自动保存回存储器。 你必须手动调用 SavePolicy() 来保存所有的策略规则

例子

我们为您提供以下示例作为参考:

文件适配器 (内置)

下面的代码演示了如何从File adapter初始化enforcer:

import "github.com/casbin/casbin"

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

它等同于如下代码:

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)

MySQL 适配器

下面展示了如何从MySQL数据库初始化一个enforcer。 此处样例中的MySQL数据库运行在127.0.0.1:3306上,用户为root,密码为空。

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)

使用自建的adapter

您可以参考如下代码来使用自建的adapter

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

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

在不同适配器之间转移/转换

如果您想将适配器从 A 转换为 B, 您可以这样做:

  1. 从 A 加载策略到内存

    e, _ := NewEnforcer(m, A)

    或者

    e.SetAdapter(A)
    e.LoadPolicy()
  2. 将您的适配器从 A 转换为 B

    e.SetAdapter(B)
  3. 将策略从内存保存到 B

    e.LoadPolicy()

在运行时进行加载或保存配置信息

如果您在初始化后仍想重载model和policy的配置(或是保存policy的配置信息),那么可以参照如下方法:

// 从CONF配置文件中加载model
e.LoadModel()
// 从文件或数据库中加载policy
e.LoadModel()
// 保存当前的policy(通常在调用Casbin API改变了配置信息后)至文件或数据库
e.SavePolicy()

自动保存

自动保存机制(Auto-Save)是adapter的特性之一。 支持自动保存机制的adapter可以自动向存储回写内存中单个policy规则的变更(删除/更新)。 与自动回写机制不同,调用SavePolicy()会直接删除所有存储中的policy规则并将当前Casbin enforcer存储在内存中的policy规则悉数持久化到存储中。 因此,当内存中的policy规则过多时,直接调用SavePolicy()会引起一些性能问题。

当适配器支持自动保存机制时,您可以通过Enforcer.EnableAutoSave() 函数来开启或关闭该机制。 默认情况下启用该选项(如果适配器支持自动保存的话)。

备注
  1. Auto-Save 特性是可选的。 Adapter可以选择是否实现它。
  2. Auto-Save 只在Casbin enforcer使用的adapter支持它时才有效。
  3. 查看上述adapter列表中的 AutoSave列,查看adapter是否支持 Auto-Save

以下示例演示了 Auto-Save的使用方法:

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

// enforcer会默认开启AutoSave机制.
a := xormadapter.NewAdapter("mysql", "mysql_username:mysql_password@tcp(127.0.0.1:3306)/")
e := casbin.NewEnforcer("examples/basic_model.conf", a)

// 禁用AutoSave机制
e.EnableAutoSave(false)

// 因为禁用了AutoSave,当前策略的改变只在内存中生效
// 这些策略在持久层中仍是不变的
e.AddPolicy(...)
e.RemovePolicy(...)

// 启用自动保存选项。
e.EnableAutoSave(true)

// 因为开启了AutoSave机制,现在内存中的改变会同步回写到持久层中
e.AddPolicy(...)
e.RemovePolicy(...)

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

如何编写 Adapter

Adapter应实现Adapter 中定义的接口,其中必须实现的为LoadPolicy(model model.Model) errorSavePolicy(model model.Model) error

其他三个函数是可选的。 如果adapter支持Auto-Save特性,则应该实现它们。

接口名类型描述
LoadPolicy()必须从持久层中加载policy规则
SavePolicy()必须将policy规则保存至持久层
AddPolicy()可选添加单条policy规则至持久层
RemovePolicy()可选从持久层删除单条policy规则
RemoveFilteredPolicy()可选从持久层删除符合筛选条件的policy规则
备注

如果适配器不支持 自动保存, 它应该为以下三个可选函数提供一个空实现。 下面是Golang的一个例子:

// AddPolicy 添加一个policy规则至持久层
func (a *Adapter) AddPolicy(sec string, ptype string, rule []string) error {
return errors.New("not implemented")
}

// RemovePolicy 从持久层删除单条policy规则
func (a *Adapter) RemovePolicy(sec string, ptype string, rule []string) error {
return errors.New("not implemented")
}

// RemoveFilteredPolicy 从持久层删除符合筛选条件的policy规则
func (a *Adapter) RemoveFilteredPolicy(sec string, ptype string, fieldIndex int, fieldValues ...string) error {
return errors.New("not implemented")
}

Casbin enforcer在调用这三个可选实现的接口时,会忽略返回的not implemented 异常。

关于如何写入适配器的详细信息。

  • 数据结构 适配器应 最少 支持六列。
  • 数据库名称: 默认数据库名称应该是 casbin
  • 表格名称 默认表名应该是 casbin_rule
  • Ptype 栏。 此列的名称应该是 ptype 而不是 p_typePtype
  • 表定义应该是 (id int priorkey, ptype varchar, v0 varchar, v1 varchar, v2 varchar, v3 varchar, v4 varchar, v5 varchar)
  • 唯一的密钥索引应该建立在列 ptype, v0, v1, v2, v3, v4, v5 上。
  • LoadFilteredPolicy需要一个 filter 作为参数。 Filter应该像这样。
    {
    "p":[ [ "alice" ], [ "bob" ] ],
    "g":[ [ "", "book_group" ], [ "", "pen_group" ] ],
    "g2":[ [ "alice" ] ]
    }

谁负责创建数据库?

我们通常约定,如果相应的数据库结构尚未建立,那么使用adapter作为policy的持久化工具时,它应具有自动创建一个名为 casbin 的数据库的能力。 请使用Xorm adapter作为参考实现:https://github.com/casbin/xorm-adapter