开始使用
Installation
go get github.com/casbin/casbin/v3
如果你要从 Casbin v2 升级到 v3,请将导入路径从 github.com/casbin/casbin/v2 更新为 github.com/casbin/casbin/v3。这也适用于所有子包(例如,v2/model 变为 v3/model)。
对于 Go modules,运行:
go get -u github.com/casbin/casbin/v3
然后更新代码中所有从 /v2 到 /v3 的导入。
对于 Maven:
<!-- https://mvnrepository.com/artifact/org.casbin/jcasbin -->
<dependency>
<groupId>org.casbin</groupId>
<artifactId>jcasbin</artifactId>
<version>1.x.y</version>
</dependency>
GraalVM Native Image Support
如果你正在使用 GraalVM 构建原生应用程序(例如,使用 Quarkus 或 Spring Native),由于 jCasbin 使用了 Aviator expression engine,因此需要特殊配置。
默认情况下,Aviator 通过 ASM 使用动态类生成,这在 GraalVM native images 中不受支持。要解决此问题,你必须配置 Aviator 使用解释器模式而不是编译模式。
对于 Quarkus applications
将以下内容添加到你的 application.properties 或 pom.xml 中:
<properties>
<quarkus.native.additional-build-args>
-J-Daviator.eval.mode=INTERPRETER
</quarkus.native.additional-build-args>
</properties>
对于其他 GraalVM native builds
在构建 native image 时设置系统属性:
-Daviator.eval.mode=INTERPRETER
或者在初始化 jCasbin 之前以编程方式配置它:
System.setProperty("aviator.eval.mode", "INTERPRETER");
此配置 将 Aviator 从其默认的编译模式切换为解释器模式。虽然这可能会对性能产生轻微影响,但通过避免运行时类生成,它实现了与 GraalVM native images 的完全兼容性。
# NPM
npm install casbin --save
# Yarn
yarn add casbin
在项目的 composer.json 中要求此包以下载该包:
composer require casbin/casbin
pip install casbin
dotnet add package Casbin.NET
# Download source
git clone https://github.com/apache/casbin-cpp.git
# Generate project files
cd casbin-cpp && mkdir build && cd build && cmake .. -DCMAKE_BUILD_TYPE=Release
# Build and install casbin
cmake --build . --config Release --target casbin install -j 10
cargo install cargo-edit
cargo add casbin
// If you use async-std as async executor
cargo add async-std
// If you use tokio as async executor, make sure you activate its `macros` feature
cargo add tokio
Casbin4D 已打包供 Delphi 10.3 Rio 使用,并可直接安装在 IDE 中。请注意,不包含可视化组件——该库由独立的单元组成,你需要独立地将它们导入到你的项目中。
luarocks install casbin
如果你收到错误 "Your user does not have write permissions in /usr/local/lib/luarocks/rocks",请以提升的权限运行命令,或使用 --local 标志安装到你的本地树中:
luarocks install casbin --local
Create a Casbin Enforcer
Casbin 依赖配置文件来指定访问控制模型。
你需要两个配置文件:model.conf 和 policy.csv。Model 文件定义你的访问控制模型;Policy 文件保存权限规则。在实践中,你只需处理一个组件——Enforcer——它在创建时会加载这两个文件。
要创建一个 Enforcer,请提供一个 Model 和一个 Adapter。
Casbin 提供了一个你可以使用的 FileAdapter。有关更多信息,请 参阅 Adapter。
- 使用带有默认 FileAdapter 的 Model 文件的示例:
import "github.com/casbin/casbin/v3"
e, err := casbin.NewEnforcer("path/to/model.conf", "path/to/policy.csv")
import org.casbin.jcasbin.main.Enforcer;
Enforcer e = new Enforcer("path/to/model.conf", "path/to/policy.csv");
import { newEnforcer } from 'casbin';
const e = await newEnforcer('path/to/model.conf', 'path/to/policy.csv');
require_once './vendor/autoload.php';
use Casbin\Enforcer;
$e = new Enforcer("path/to/model.conf", "path/to/policy.csv");
import casbin
e = casbin.Enforcer("path/to/model.conf", "path/to/policy.csv")
using NetCasbin;
var e = new Enforcer("path/to/model.conf", "path/to/policy.csv");
#include <iostream>
#include <casbin/casbin.h>
int main() {
// Create an Enforcer
casbin::Enforcer e("path/to/model.conf", "path/to/policy.csv");
// your code ..
}
var
casbin: ICasbin;
begin
casbin := TCasbin.Create('path/to/model.conf', 'path/to/policy.csv');
...
end
use casbin::prelude::*;
// If you use async_td as async executor
#[cfg(feature = "runtime-async-std")]
#[async_std::main]
async fn main() -> Result<()> {
let mut e = Enforcer::new("path/to/model.conf", "path/to/policy.csv").await?;
Ok(())
}
// If you use tokio as async executor
#[cfg(feature = "runtime-tokio")]
#[tokio::main]
async fn main() -> Result<()> {
let mut e = Enforcer::new("path/to/model.conf", "path/to/policy.csv").await?;
Ok(())
}
local Enforcer = require("casbin")
local e = Enforcer:new("path/to/model.conf", "path/to/policy.csv") -- The Casbin Enforcer
- 使用带有替代 Adapter 的 Model 文本的示例:
import (
"log"
"github.com/casbin/casbin/v3"
"github.com/casbin/casbin/v3/model"
xormadapter "github.com/casbin/xorm-adapter/v2"
_ "github.com/go-sql-driver/mysql"
)
// Initialize a Xorm adapter with MySQL database.
a, err := xormadapter.NewAdapter("mysql", "mysql_username:mysql_password@tcp(127.0.0.1:3306)/")
if err != nil {
log.Fatalf("error: adapter: %s", err)
}
m, err := model.NewModelFromString(`
[request_definition]
r = sub, obj, act
[policy_definition]
p = sub, obj, act
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act
`)
if err != nil {
log.Fatalf("error: model: %s", err)
}
e, err := casbin.NewEnforcer(m, a)
if err != nil {
log.Fatalf("error: enforcer: %s", err)
}
import casbin
import casbin_sqlalchemy_adapter
# Use SQLAlchemy Casbin adapter with SQLLite DB
adapter = casbin_sqlalchemy_adapter.Adapter('sqlite:///test.db')
# Create a config model policy
with open("rbac_example_model.conf", "w") as f:
f.write("""
[request_definition]
r = sub, obj, act
[policy_definition]
p = sub, obj, act
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act
""")
# Create enforcer from adapter and config policy
e = casbin.Enforcer('rbac_example_model.conf', adapter)
Check Permissions
在资源被访问之前,立即在你的代码中添加一个 enforcement check:
sub := "alice" // the user that wants to access a resource.
obj := "data1" // the resource that is going to be accessed.
act := "read" // the operation that the user performs on the resource.
ok, err := e.Enforce(sub, obj, act)
if err != nil {
// handle err
}
if ok == true {
// permit alice to read data1
} else {
// deny the request, show an error
}
// You could use BatchEnforce() to enforce some requests in batches.
// This method returns a bool slice, and this slice's index corresponds to the row index of the two-dimensional array.
// e.g. results[0] is the result of {"alice", "data1", "read"}
results, err := e.BatchEnforce([][]interface{}{{"alice", "data1", "read"}, {"bob", "data2", "write"}, {"jack", "data3", "read"}})
String sub = "alice"; // the user that wants to access a resource.
String obj = "data1"; // the resource that is going to be accessed.
String act = "read"; // the operation that the user performs on the resource.
if (e.enforce(sub, obj, act) == true) {
// permit alice to read data1
} else {
// deny the request, show an error
}
如果你在 GraalVM native image 环境中运行 jCasbin,请确保你已按照上述安装部分所述配置 Aviator 使用解释器模式。如果没有此配置,你将遇到因运行时类生成尝试而导致的 UnsupportedFeatureError。
const sub = 'alice'; // the user that wants to access a resource.
const obj = 'data1'; // the resource that is going to be accessed.
const act = 'read'; // the operation that the user performs on the resource.
if ((await e.enforce(sub, obj, act)) === true) {
// permit alice to read data1
} else {
// deny the request, show an error
}
$sub = "alice"; // the user that wants to access a resource.
$obj = "data1"; // the resource that is going to be accessed.
$act = "read"; // the operation that the user performs on the resource.
if ($e->enforce($sub, $obj, $act) === true) {
// permit alice to read data1
} else {
// deny the request, show an error
}
sub = "alice" # the user that wants to access a resource.
obj = "data1" # the resource that is going to be accessed.
act = "read" # the operation that the user performs on the resource.
if e.enforce(sub, obj, act):
# permit alice to read data1
pass
else:
# deny the request, show an error
pass
var sub = "alice"; // the user that wants to access a resource.
var obj = "data1"; // the resource that is going to be accessed.
var act = "read"; // the operation that the user performs on the resource.
if (await e.EnforceAsync(sub, obj, act))
{
// permit alice to read data1
}
else
{
// deny the request, show an error
}
casbin::Enforcer e("../assets/model.conf", "../assets/policy.csv");
if (e.Enforce({"alice", "/alice_data/hello", "GET"})) {
std::cout << "Enforce OK" << std::endl;
} else {
std::cout << "Enforce NOT Good" << std::endl;
}
if (e.Enforce({"alice", "/alice_data/hello", "POST"})) {
std::cout << "Enforce OK" << std::endl;
} else {
std::cout << "Enforce NOT Good" << std::endl;
}
if casbin.enforce(['alice,data1,read']) then
// Alice is super happy as she can read data1
else
// Alice is sad
let sub = "alice"; // the user that wants to access a resource.
let obj = "data1"; // the resource that is going to be accessed.
let act = "read"; // the operation that the user performs on the resource.
if e.enforce((sub, obj, act)).await? {
// permit alice to read data1
} else {
// error occurs
}
if e:enforce("alice", "data1", "read") then
-- permit alice to read data1
else
-- deny the request, show an error
end
Casbin 提供了用于运行时权限管理的 API。例如,你可以检索分配给用户的所有角色:
roles, err := e.GetRolesForUser("alice")
List<String> roles = e.getRolesForUser("alice");
const roles = await e.getRolesForUser('alice');
$roles = $e->getRolesForUser("alice");
roles = e.get_roles_for_user("alice")
var roles = e.GetRolesForUser("alice");
roles = e.rolesForEntity("alice")
let roles = e.get_roles_for_user("alice");
local roles = e:GetRolesForUser("alice")
有关更多示例,请参阅 Management API 和 RBAC API。你还可以浏览每种语言仓库中的测试用例。
Comments are powered by giscus and GitHub Discussions. They load from giscus.app and GitHub only after you click the button below.