casbin使用及技术原理

本文介绍了Casbin,一个支持ACL、RBAC和ABAC的高效权限管理框架,重点讲解了其原理、Java集成、规则配置与优化策略。通过实例演示了如何在Java应用中使用Casbin进行权限校验,并探讨了架构、性能优化和企业实践。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.概述

1.1 Casbin描述

Casbin 是一个强大的、高效的开源访问控制框架,其权限管理机制支持多种访问控制模型。

1.2 Casbin 是什么?

Casbin 可以:

  1. 支持自定义请求的格式,默认的请求格式为{subject, object, action}。
  2. 具有访问控制模型model和策略policy两个核心概念。
  3. 支持RBAC中的多层角色继承,不止主体可以有角色,资源也可以具有角色。
  4. 支持内置的超级用户 例如:root 或 administrator。超级用户可以执行任何操作而无需显式的权限声明。
  5. 支持多种内置的操作符,如 keyMatch,方便对路径式的资源进行管理,如 /foo/bar 可以映射到 /foo*

Casbin 不能:

  1. 身份认证 authentication(即验证用户的用户名和密码),Casbin 只负责访问控制。应该有其他专门的组件负责身份认证,然后由 Casbin 进行访问控制,二者是相互配合的关系。
  2. 管理用户列表或角色列表。 Casbin 认为由项目自身来管理用户、角色列表更为合适, 用户通常有他们的密码,但是 Casbin 的设计思想并不是把它作为一个存储密码的容器。 而是存储RBAC方案中用户和角色之间的映射关系。

1.3 Casbin 支持以下编程语言:

Casbin

jCasbin

node-Casbin

PHP-Casbin

可用于生产环境

可用于生产环境

可用于生产环境

可用于生产环境

PyCasbin

Casbin.NET

Casbin-C++

Casbin-RS

可用于生产环境

可用于生产环境

可用于生产环境

可用于生产环境

1.4 在不同语言中支持的特性

特性

Go

Java

Node.js

PHP

Python

C#

Delphi

Rust

C++

Lua

Dart

Elixir

ACL

RBAC

ABAC (attribute)

其他等等

官网测试数据

1.5 使用的企业

1.6 学习地址

官网地址:Casbin · 一个支持如ACL, RBAC, ABAC等访问模型,可用于Golang, Java, C/C++, Node.js, Javascript, PHP, Laravel, Python, .NET (C#), Delphi, Rust, Ruby, Lua (OpenResty), Dart (Flutter)和Elixir的授权库。

git 地址:GitHub - casbin/jcasbin: An authorization library that supports access control models like ACL, RBAC, ABAC in Java

集成casbin-spring-boot-starter地址:GitHub - jcasbin/casbin-spring-boot-starter: Casbin Spring Boot Starter

2.casbin使用

2.1引入java pom文件:

<dependency>
                <groupId>org.casbin</groupId>
                <artifactId>casbin-spring-boot-starter</artifactId>
                <version> 0.1.2 </version>
</dependency>

2.2 引入校验规则

RBAC 规则,其他规则可以看官网git地址案例

model.config文件

# 请求定义 例如 admin, api/bios/user/detail, post
[request_definition]
r = sub, obj, act

# 策略定义 例如 admin, api/bios/user/detail, get
[policy_definition]
p = sub, obj, act

# 角色定义 色继承关系的前项和后项,
# 例如 g  r:test, r:root 代表用户拥有两个角色
[role_definition]
g = _, _

# 策略的结果,一般是固定的。  p.eft 代表决策结果, 意思就是:如果存在一个匹配的策略规则就通过。
[policy_effect]
e = some(where (p.eft == allow))

# 请求和策略的匹配规则
# g(r.sub, p.sub) 代表 用户下的角色匹配, r.obj == p.obj 代表对象一致, r.act == p.act 代表action一致
[matchers]
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act

2.3 添加配置文件,

application.yml

casbin:
  #是否开启Casbin,默认开启
  enableCasbin: true
  #是否使用线程同步的Enforcer,默认false
  useSyncedEnforcer: false
  #是否开启策略自动保存,如适配器支持该功能,默认开启
  autoSave: true
  #存储类型[file,jdbc],目前支持的jdbc数据库[mysql(mariadb),h2,oracle,postgresql,db2]
  #欢迎编写并提交您所使用的jdbc适配器,参见:org.casbin.adapter.OracleAdapter
  #jdbc适配器将主动寻找您在spring.datasource配置的数据源信息
  #默认使用jdbc,并使用内置h2数据库进行内存存储
  storeType: jdbc
  #当使用jdbc时,定制化数据库表名,默认表名是casbin_rule
  tableName: casbin_rule
  #数据源初始化策略[create(自动创建数据表,如已创建则不再进行初始化),never(始终不进行初始化)]
  initializeSchema: create
  #本地模型配置文件地址,约定默认读取位置:classpath:casbin/model.conf
  model: classpath:casbin/model.conf
  #如默认位置未找到模型配置文件,且casbin.model未正确设置,则使用内置默认rbac模型,默认生效
  useDefaultModelIfModelNotSetting: true
  #本地策略配置文件地址,约定默认读取位置:classpath:casbin/policy.csv
  #如默认位置未找到配置文件,将会抛出异常
  #该配置项仅在casbin.storeType设定为file时生效
  policy: classpath:casbin/policy.csv
  #是否开启CasbinWatcher机制,默认不开启
  #如开启该机制,则casbin.storeType必须为jdbc,否则该配置无效
  enableWatcher: false
  #CasbinWatcher通知方式,默认使用Redis进行通知同步,暂时仅支持Redis
  #开启Watcher后需手动添加spring-boot-starter-data-redis依赖
  watcherType: redis
  #异常抛出时机控制
  exception:

启动后系统自动创建持久化表。

2.4 插入创建RBAC权限

用户角色关系: u:11 r:test

角色权限关系: r:test /api/test1

 

2.5 代码使用:

public class CasbinPolicyManager {
    
    @Autowired
    private Enforcer enforcer;
    
    
    
    /**
    * 规则权限校验
    *
    * @param userId 请求对象
    * @param url    数据
    * @return boolean
    */
    public Boolean enforceUserUrl(Long userId, String url, String type) {
        return enforcer.enforce("u:11", "api/test1", "get");
    }
    
     /**
     * 为用户新增角色
     *
     * @param userId
     * @param roleIds
     */
    public void addUserRole(Long userId, Set<Long> roleIds) {
        enforcer.addRoleForUser(userSubject(userId), roleSubject(roleId));
    }
    
    /**
     * 为角色新增权限
     *
     * @param userId
     * @param roleIds
     */
      public void addRolePermissionPolicy(Long roleId, String url, String type) {
        enforcer.addPolicy(Lists.newArrayList(roleSubject(roleId), url, type));
    }
    
    
}
 

3.casbin分析

3.1 jcasbin架构图

3.2 jcasbinn内部流程图

省略,详细流程见第四章

3.3 落地业务流程图

4 功能流程分析

4.1启动数据初始化

CasbinAutoConfiguration

 

 

4.2资源权限校验匹配

CoreEnforcer#enforce

Aviator是一个高效,轻量级的表达式引擎。Aviator 的基本过程是将表达式直接翻译成对应的 java 字节码执行,整个过程最多扫两趟(开启执行优先模式,如果是编译优先模式下就一趟),这样就保证了它的性能超越绝大部分解释性的表达式引擎,测试也证明如此。

  1. 编译型规则表达式引擎:预先编译成可执行对象,运行时多次执行;
  2. 解释型规则表达式引擎:不需要预先进行编译,在运行时,要先进行解释再运行

java实例:

Expression expression = aviatorEval.compile(expString, true);
Object result = expression.execute(parameters);

更多了解,官网:1. 介绍 · 语雀

4.3 资源权限校验新增

4.4资源权限更新

目前jdbcAdapter的更新走 remove , insert

1:mysql更新代价比较大,走insert效率比较高

2:集合进行全量删除 +全量插入 > 集合遍历 + 增量更新 + 增量删除

bd更新

remove + insert

// 1.缓存更新

注意:禁止直接更新数据库,因为缓存没有更新,会有缓存,db不一致问题

可以通过接口更新资源信息

4.功能性能优化

4.1 高访量

单个Casbin实例每秒就能收到10000条请求。 在这种情况下,仅靠一个Casbin实例通常难以处理完所有请求。 现在有两种解决方案:

  1. 运用多线程来运行多个Casbin实例,这样以来您就可以充分利用机器中的所有内核。 详情请参阅:多线程
  2. 将Casbin实例部署到机器集群(多台机器)。 使用Watcher来确保所有Casbin实例运行一致。 详情请参阅: Watcher

4.2 大量的策略规则数据

在云或多租户环境中,可能需要数百万条策略规则。 每次执行请求甚至是在最初期加载策略规则的速度非常缓慢。 这类事件通常可以通过以下几种方式缓解:

1. 精致的模型和策略将抽象每个用户/租户的重复逻辑,

2.通过共享让Casbin 的执行者只需要加载一套小套策略规则,详情请参阅 :策略子集加载

3.以授予RBAC角色权限,取代直接授予用户权限。 Casbin的RBAC是通过角色继承树来实现的(作为缓存)。 因此授予类似Alice这样的用户权限,Casbin只使用O(1) 时间查询RBAC树来获取角色用户关系并执行操作。 如果您的 g 规则不会经常改变,那么RBAC 树将不需要进行更新。

<think>好的,我需要帮助用户在Go中使用Casbin实现基于角色的访问控制(RBAC)。首先,我得回忆一下Casbin的基本概念和RBAC模型的结构。Casbin使用模型配置文件(model.conf)和策略文件(policy.csv)来定义访问控制规则。 用户提供的引用内容中有几个关键点。引用[1]提到ABAC的用法,但用户的问题是关于RBAC的,所以可能需要暂时忽略这部分。引用[2]和[3]给出了Go代码的示例,其中初始化了Enforcer并测试了权限。这应该是实现RBAC的核心步骤。 首先,用户需要创建一个模型配置文件(rbac_model.conf)。RBAC模型通常包括角色定义、资源、操作以及角色继承。例如,使用角色继承的话,可以通过g来定义角色层次结构,比如admin继承user的权限。然后,策略文件(rbac.csv)需要定义角色与用户的关系,以及角色对资源的访问权限。 接下来,在Go代码中,用户需要导入Casbin库,创建Enforcer实例,加载模型和策略文件。然后,使用Enforce方法来检查权限。引用[3]中的TestRBAC函数展示了如何初始化Enforcer并进行权限检查。需要注意的是,代码中的策略文件路径是否正确,以及错误处理是否完善。 用户可能需要了解如何动态添加或删除策略。例如,使用e.AddPolicy()或e.RemovePolicy()来管理策略。这部分在示例中没有提到,但实际应用中可能很重要,应该包含在回答中。 另外,引用中提到ABAC的部分可能让用户混淆,需要明确指出RBAC和ABAC的区别,确保用户不会误用操作符。同时,注意引用[1]提到某些版本不支持,但用户的问题是关于Go的实现,而引用中的代码是Go的,所以可以确认Go版本支持RBAC。 最后,生成相关问题时要围绕RBAC的实现、模型配置、策略管理和扩展功能展开,帮助用户深入理解。确保回答结构清晰,分步骤说明,代码示例正确,并引用提供的资料适当标注来源。</think>以下是如何在Go中使用Casbin实现基于角色的访问控制(RBAC)的分步说明: ### 1. 创建RBAC模型文件 新建`rbac_model.conf`文件定义访问控制逻辑: ``` [request_definition] r = sub, obj, act [policy_definition] p = sub, obj, act [role_definition] g = _, _ [policy_effect] e = some(where (p.eft == allow)) [matchers] m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act ``` 该模型实现: - `g = _, _` 定义角色继承关系 - 匹配规则要求用户角色、资源对象和操作都符合策略[^3] ### 2. 准备策略文件 创建`rbac.csv`策略文件: ``` p, admin, project, read p, admin, project, write g, alice, admin ``` 表示: - admin角色有project的读写权限 - 用户alice被赋予admin角色[^3] ### 3. 实现Go代码 ```go package main import ( "fmt" "log" "github.com/casbin/casbin/v2" ) func main() { e, err := casbin.NewEnforcer("rbac_model.conf", "rbac.csv") if err != nil { log.Fatalf("初始化失败: %v", err) } // 验证alice的权限 if ok, _ := e.Enforce("alice", "project", "read"); ok { fmt.Println("alice有读取权限") } // 动态添加策略 e.AddPolicy("manager", "report", "read") e.AddRoleForUser("bob", "manager") } ``` 代码说明: 1. 创建执行器加载模型和策略 2. 使用`Enforce`验证权限 3. 演示动态添加策略和角色[^2] ### 4. 高级功能 - **角色继承**:在策略文件添加`g, admin, user`实现角色继承 - **层级资源**:使用`keyMatch2`匹配路径参数 - **持久化**:配合数据库适配器存储策略
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值