在Casbin中,适配器(adapter,Casbin的中间件)实现了policy规则写入持久层的细节。 Casbin的用户可以调用adapter的LoadPolicy()方法从持久层中加载policy规则, 同样也可以调用SavePolicy()方法将Policy规则保存到持久层中 。 为了保持代码轻量, 我们没有将adapter的代码放在主库中。

这里罗列了支持的适配器

下面是一些您需要了解的内容:

  • 在调用方法 casbin.NewEnforcer()时,如果没有显式或隐式地指定adapter, 那么policy将会自动以默认形式加载;
  • 您可以调用e.LoadPolicy()方法从存储文件/持久层中加载policy规则;
  • 如果您使用的adapter不支持 Auto-Save 的特性,那么当Policy规则发生改变时,adapter将不会自动持久化这些变更。 此时,您需要手动调用 SavePolicy() 方法来保存所有的policy规则。

示例

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

File adapter(内置)

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

  1. import "github.com/casbin/casbin"
  2. e := casbin.NewEnforcer("examples/basic_model.conf", "examples/basic_policy.csv")

它等同于如下代码:

  1. import (
  2. "github.com/casbin/casbin"
  3. "github.com/casbin/casbin/file-adapter"
  4. )
  5. a := fileadapter.NewAdapter("examples/basic_policy.csv")
  6. e := casbin.NewEnforcer("examples/basic_model.conf", a)

MySQL adapter

如下展示了如何从MYSQL数据库初始化enforcer。本例中使用的MYSQL地址为127.0.0.1:3306,用户为root且密码为空。

  1. import (
  2. "github.com/casbin/casbin"
  3. "github.com/casbin/mysql-adapter"
  4. )
  5. a := mysqladapter.NewAdapter("mysql", "root:@tcp(127.0.0.1:3306)/")
  6. e := casbin.NewEnforcer("examples/basic_model.conf", a)

使用自建的adapter

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

  1. import (
  2. "github.com/casbin/casbin"
  3. "github.com/your-username/your-repo"
  4. )
  5. a := yourpackage.NewAdapter(params)
  6. e := casbin.NewEnforcer("examples/basic_model.conf", a)

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

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

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

目前支持的adapter列表

在Casbin中,adapter实现了policy的存储细节。 为了保持轻量, 我们没有将适配器代码放在主库当中。 以下是Casbin提供的adapter列表:

:我们欢迎任何第三方的adapter实现,如果您通知我们,我们很乐意将它加入以下列表 :)

适配器 类型 作者 描述
File Adapter (内置) File Casbin .CSV(逗号分隔values的存储文件)的持久化adapter实现
Filtered File Adapter (built-in) File @faceless-saint Persistence for .CSV (Comma-Separated Values) files with policy subset loading support
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
Beego ORM Adapter ORM Casbin MySQL, PostgreSQL, Sqlite3 are supported by Beego ORM
MongoDB Adapter NoSQL Casbin Persistence for MongoDB
Cassandra Adapter NoSQL Casbin Persistence for Apache Cassandra DB
Consul Adapter KV store @ankitm123 Persistence for HashiCorp Consul
Redis Adapter KV store Casbin Persistence for Redis
Etcd Adapter KV store Casbin Persistence for etcd
Protobuf Adapter Stream Casbin Persistence for Google Protocol Buffers
JSON Adapter String Casbin Persistence for JSON
String Adapter String @qiangmzsx Persistence for String
RQLite Adapter SQL EDOMO Systems Persistence for RQLite
PostgreSQL Adapter SQL Going Persistence for PostgreSQL
RethinkDB Adapter NoSQL @adityapandey9 Persistence for RethinkDB
DynamoDB Adapter NoSQL HOOQ Persistence for Amazon DynamoDB
Minio/AWS S3 Adapter Object storage Soluto Persistence for Minio and Amazon S3
Bolt Adapter KV store @wirepair Persistence for Bolt

自动保存机制

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

如果一个adapter支持自动保存特性,您可以通过调用Enforcer.EnableAutoSave()方法将此功能打开。如果您使用的adapter支持此功能,这个特性会在启动时默认开启。

注意:

  • 对于一个adapter来说,自动保存机制的实现是可选的
  • Casbin enforcer的自动保存特性受制于adapter对该特性的实现;
  • 目前支持自动保存机制的adapter如下:
    |支持with Auto-Save的Adapter|类型|作者|描述
    |——-
    |Xorm Adapter|ORM|Casbin|通过 Xorm实现,支持MySQL, PostgreSQL, TiDB, SQLite, SQL Server, Oracle等多种存储引擎的adapter
    |Gorm Adapter|ORM|Casbin|通过 Gorm实现,支持MySQL, PostgreSQL, Sqlite3, SQL Server等多种存储引擎的adapter
    |Beego ORM Adapter|ORM|Casbin|通过Beego ORM实现,支持MySQL, PostgreSQL, Sqlite3等多种存储引擎的适配器
    |MongoDB Adapter|NoSQL|Casbin|MongoDB的持久化adapter实现
    |RQLite Adapter|SQL|EDOMO Systems|RQLite的持久化adapter实现
    |RethinkDB Adapter|NoSQL|@adityapandey9|RethinkDB的持久化adapter实现

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

  1. import (
  2. "github.com/casbin/casbin"
  3. "github.com/casbin/xorm-adapter"
  4. _ "github.com/go-sql-driver/mysql"
  5. )
  6. // enforcer会默认开启AutoSave机制.
  7. a := xormadapter.NewAdapter("mysql", "mysql_username:mysql_password@tcp(127.0.0.1:3306)/")
  8. e := casbin.NewEnforcer("examples/basic_model.conf", a)
  9. // 禁用AutoSave机制
  10. e.EnableAutoSave(false)
  11. // 因为禁用了AutoSave,当前策略的改变只在内存中生效
  12. // 这些策略在持久层中仍是不变的
  13. e.AddPolicy(...)
  14. e.RemovePolicy(...)
  15. // 开启AutoSave机制
  16. e.EnableAutoSave(true)
  17. // 因为开启了AutoSave机制,现在内存中的改变会同步回写到持久层中
  18. e.AddPolicy(...)
  19. 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

剩余3个可选实现接口。当然,如果此Adapter要支持Auto-Save机制,这些接口的实现也是必不可少的。以下为接口描述:

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

注意:如果编写的Adapter不打算实现Auto-Save机制,应当给出前文提到其他3个接口的默认实现 如果所有接口未被实现,Golang会抛出编译异常。 以下为它们的默认实现参考:

  1. // AddPolicy 添加一个policy规则至持久层
  2. func (a *Adapter) AddPolicy(sec string, ptype string, rule []string) error {
  3. return errors.New("not implemented")
  4. }
  5. // RemovePolicy 从持久层删除单条policy规则
  6. func (a *Adapter) RemovePolicy(sec string, ptype string, rule []string) error {
  7. return errors.New("not implemented")
  8. }
  9. // RemoveFilteredPolicy 从持久层删除符合筛选条件的policy规则
  10. func (a *Adapter) RemoveFilteredPolicy(sec string, ptype string, fieldIndex int, fieldValues ...string) error {
  11. return errors.New("not implemented")
  12. }

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

关于数据库表结构的创建

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

原文: https://casbin.org/docs/zh-CN/policy-storage