跳转至主要内容

适配器

在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 AdapterORMCasbinMySQL, PostgreSQL, Sqlite3, SQL Server are supported by GORM
GORM Adapter ExORMCasbinMySQL, PostgreSQL, Sqlite3, SQL Server are supported by GORM
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 AdapterORM@Blank-XuMySQL, PostgreSQL, SQL Server, SQLite3 由 master 分支支持,Oracle由oracle 分支受到sqlx的支持
GF ORM AdapterORM@vance-liuMySQL, SQLite, PostgreSQL, Oracle, SQL Server are supported by GoFrame ORM
GoFrame ORM AdapterORM@kotlin2018MySQL, SQLite, PostgreSQL, Oracle, SQL Server are supported by GoFrame ORM
gf-adapterORM@zcycMySQL, SQLite, PostgreSQL, Oracle, SQL Server are supported by GoFrame ORM
Gdb AdapterORM@jxo-meMySQL, SQLite, PostgreSQL, Oracle, SQL Server are supported by GoFrame ORM
GoFrame V2 AdapterORM@hailazMySQL, SQLite, PostgreSQL, Oracle, SQL Server are supported by 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. LoadPolicy()
// 保存当前的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()optional从持久层删除单条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