casbin使用及技术原理

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使用及技术原理_第1张图片

casbin使用及技术原理_第2张图片

casbin使用及技术原理_第3张图片

casbin使用及技术原理_第4张图片

Casbin

jCasbin

node-Casbin

PHP-Casbin

可用于生产环境

可用于生产环境

可用于生产环境

可用于生产环境

casbin使用及技术原理_第5张图片

casbin使用及技术原理_第6张图片

casbin使用及技术原理_第7张图片

casbin使用及技术原理_第8张图片

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)

其他等等

官网测试数据

casbin使用及技术原理_第9张图片

1.5 使用的企业

casbin使用及技术原理_第10张图片

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文件:


                org.casbin
                casbin-spring-boot-starter
                 0.1.2 

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

casbin使用及技术原理_第11张图片

 

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 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架构图

casbin使用及技术原理_第12张图片

3.2 jcasbinn内部流程图

省略,详细流程见第四章

3.3 落地业务流程图

casbin使用及技术原理_第13张图片

4 功能流程分析

4.1启动数据初始化

CasbinAutoConfiguration

 
  

 casbin使用及技术原理_第14张图片

4.2资源权限校验匹配

CoreEnforcer#enforce

casbin使用及技术原理_第15张图片

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

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

java实例:

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

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

4.3 资源权限校验新增

casbin使用及技术原理_第16张图片

4.4资源权限更新

目前jdbcAdapter的更新走 remove , insert

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

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

bd更新

remove + insert

casbin使用及技术原理_第17张图片

// 1.缓存更新

casbin使用及技术原理_第18张图片

注意:禁止直接更新数据库,因为缓存没有更新,会有缓存,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 树将不需要进行更新。

你可能感兴趣的:(spring,boot,java)