본문으로 건너뛰기

Adapters

Casbin은 adapters를 통해 정책을 로드하고 저장합니다. enforcer는 규칙을 로드하기 위해 LoadPolicy()를 호출하며, 지원되는 경우 영구 저장을 위해 SavePolicy()를 호출합니다. 어댑터는 코어 라이브러리를 작게 유지하기 위해 별도 패키지로 구현됩니다.

지원되는 어댑터​

아래에는 언어별 어댑터 목록이 나와 있습니다. 서드파티 어댑터를 추가하려면 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. 어댑터(명시적 또는 암시적)와 함께 casbin.NewEnforcer()를 호출하면 정책이 자동으로 로드됩니다.
  2. 저장소에서 정책을 새로고침하려면 e.LoadPolicy()를 호출하세요.
  3. Auto-Save 지원이 없는 경우, 정책을 수정할 때 어댑터가 변경 사항을 자동으로 영구 저장할 수 없습니다. 모든 규칙을 영구 저장하려면 SavePolicy()를 수동으로 호출하세요.

예제​

몇 가지 어댑터 사용 예제가 다음과 같습니다:

File 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 데이터베이스 연결, root 사용자 및 비밀번호 없이 enforcer를 초기화합니다:

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)

자체 스토리지 어댑터 사용​

커스텀 어댑터를 통합합니다:

import (
"github.com/casbin/casbin/v3"
"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()
  1. 어댑터 A에서 B로 전환
e.SetAdapter(B)
  1. 메모리에서 B로 정책 저장
e.SavePolicy()

런타임 시 Load/Save​

초기화 후 모델과 정책을 다시 로드하거나 정책 변경 사항을 영구 저장하려면:

// 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. Auto-Save는 Enforcer의 어댑터가 이를 지원할 때만 작동합니다.
  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

어댑터 작성 방법​

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 Enforcer는 이러한 선택적 메서드를 호출할 때 "not implemented" 오류를 무시합니다.

어댑터 구현 요구 사항:

  • Data Structure. 최소한 6개의 컬럼 읽기를 지원해야 합니다.
  • Database Name. 기본값은 casbin입니다.
  • Table Name. 기본값은 casbin_rule입니다.
  • Ptype Column. 이름은 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는 다음과 같은 구조의 filter 매개변수를 허용합니다:
{
"p": ["", "domain1"],
"g": ["", "", "domain1"]
}

DB 생성 책임은 누구에게 있나요?​

관례적으로, 어댑터는 casbin 데이터베이스가 존재하지 않으면 자동으로 생성하고 정책 저장을 위해 사용해야 합니다. 참고 구현: https://github.com/apache/casbin-xorm-adapter

Update Adapter​

UpdateAdapter 인터페이스는 기본 Adapter 인터페이스를 확장하여 스토리지에서 정책을 직접 업데이트할 수 있게 합니다. 기존 규칙을 수정할 때 제거 후 추가 순서보다 더 효율적인 접근 방식입니다.

UpdateAdapter를 구현하는 어댑터는 다음 메서드를 제공합니다:

MethodTypeDescription
UpdatePolicy()선택 사항저장소에서 단일 정책 규칙을 업데이트합니다.
UpdatePolicies()선택 사항저장소에서 여러 정책 규칙을 업데이트합니다.
UpdateFilteredPolicies()선택 사항필터와 일치하는 정책 규칙을 저장소에서 업데이트합니다.

예시​

Update 어댑터 사용법:

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",
)

Update 어댑터 작성 방법​

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() 작업의 조합으로 대체됩니다.

Context Adapter​

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)
}

Context 어댑터 작성 방법​

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.