casbin学习笔记

2023-05-16

安装

$ go get github.com/casbin/casbin/v2
import "github.com/casbin/casbin/v2"

func main() {
	e, err := casbin.NewEnforcer("path/to/model.conf", "path/to/policy.csv")
}

创建文件

在当前目录下创建model.confpolicy.csv文件,JetBrains有Casbin插件,如果装有该插件,model.conf图标会变

model.conf内装的就是模型,policy.csv装的就是policy(暂时先用csv装一下)

示例:

[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
p,zhangsan,data1,read

开始用

package main

import (
	"fmt"
	"github.com/casbin/casbin/v2"
)

func main() {
	e, err := casbin.NewEnforcer("model.conf", "policy.csv") // 模型与policy的路径

	sub := "alice" // 想要访问资源的用户。
	obj := "data1" // 将被访问的资源。
	act := "read"  // 用户对资源执行的操作。

	ok, err := e.Enforce(sub, obj, act) //Enforce决定一个 “subject” 是否能够用 “action” 操作访问 “object” 

	if err != nil {
        // 异常处理
		fmt.Println(err)
		return
	}

	if ok == true {
		// 允许alice读取data1
		fmt.Println("允许alice的操作")
	} else {
		// 拒绝请求,抛出异常
		fmt.Println("拒绝alice的操作")
	}
}

此时运行结果一定是

拒绝alice的操作

进程 已完成,退出代码为 0

因为alice没有在policy中给予任何权限

查询指定字段的policy

GetFilteredPolicy()

GetFilteredPolicy 获取策略中的所有授权规则,我们可以指定字段筛选器。

例如:

filteredPolicy := e.GetFilteredPolicy(0, "alice")
// 查询v0字段为alice的所有policy

v0字段:存放到数据库中的policy有这样几列

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4wq5VXp0-1651581293719)(casbin图片/image-20220503172422514.png)]

而v0字段就是sub字段

适配器

全部适配器

gorm 适配器

gorm适配器

直接把这玩意儿粘贴过去就行,这玩意儿就在github的readme里

import (
	"github.com/casbin/casbin/v2"
	gormadapter "github.com/casbin/gorm-adapter/v3"
	_ "github.com/go-sql-driver/mysql"
)

func main(){
    // 初始化Gorm适配器并在Casbin enforcer中使用:
	// 适配器将使用名为“casbin”的MySQL数据库。
	// 如果它不存在,适配器将自动创建它。
	// 您还可以将已经存在的gorm实例与gormadapter一起使用。NewAdapterByDB(gormInstance)
	a, _ := gormadapter.NewAdapter("mysql", "mysql_username:mysql_password@tcp(127.0.0.1:3306)/") // 你的驱动程序和数据源。
	e, _ := casbin.NewEnforcer("./model.conf", a)
	// 或者您可以使用现有的数据库“abc”,如下所示:
	// 适配器将使用名为“casbin_rule”的表。
	// 如果它不存在,适配器将自动创建它。
	// a := gormadapter.NewAdapter("mysql", "mysql_username:mysql_password@tcp(127.0.0.1:3306)/abc", true)
	
    // 如果你的数据库中既没有名为casbin的数据库,也没有名为casbin_rule的表,那么直接用
    // a, _ := gormadapter.NewAdapter("mysql", "mysql_username:mysql_password@tcp(127.0.0.1:3306)/")即可,它会自动创建
}


增删改查Policy

这里就先使用AddPolicy()来写增,其他的查API

// 增加一条Policy
addPolicy, err := e.AddPolicy("alice", "data2", "read") // 添加成功返回true,已存在返回false
if err != nil {
    fmt.Println(err)
    return
}
fmt.Println(addPolicy)

增加一个grouping

这一步一定要注意看自己的Model是否有,否则会报错

[role_definition]
g = _, _

[matchers]
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act
// 增加一个grouping
added,err := e.AddGroupingPolicy("alice", "data1_admin")
fmt.Println(added)
fmt.Println(err)

RemovePolicy(),其他查api

removed, err := e.RemovePolicy("alice", "data2", "read")

删 groupingPolicy 用RemoveGroupingPolicy()

UpdatePolicy()改,其他查api

func (e *Enforcer) UpdatePolicy(oldPolicy []string, newPolicy []string) (bool, error)

// 例:
updated, err := e.UpdatePolicy([]string{"alice", "data1", "read"}, []string{"alice", "data2", "read"})

改groupingPolicy查api

policy := e.GetPolicy()
fmt.Println(policy)

自定义函数

首先自己写一个函数,返回一个布尔类型

// 随便写一个
func KeyMatch(key1 string, key2 string) bool {
    return key1 == key2
}

然后用interface{}类型的接口包装它

func KeyMatchFunc(args ...interface{}) (interface{},error){
    name1 := args[0].(string)
    name2 := args[1].(string)
    
    return (bool)(keyMatch(name1,name2)),nil
}

最后在casbin的执行者(enforcer)中注册这个函数

// 第一个参数是在模型中,这个自定义函数的名字
// 第二个参数是刚才用来包装的interface{}类型的接口
e.AddFunction("my_func",KeyMatchFunc)

最后便可在模型conf中使用这个函数

[matchers]
m = my_func(r.sub, p.sub) && r.obj == p.obj  && r.act == p.act

记了一点点的api

Casbin API

添加权限

AddPolicy()

AddPolicy 向当前策略添加授权规则。 如果规则已经存在,函数返回false,并且不会添加规则。 否则,函数通过添加新规则并返回true。

如果当前的policy是在本地的csv文件中存储,则这条policy不会添加进csv文件中

但在数据库中存储的话,这条policy会存进数据表中

added, err := e.AddPolicy('eve', 'data3', 'read')

查询所有policy

policy := e.GetPolicy()

PERM元模型

定义一个策略(Policy) 定义一个匹配规则(Matchers) 通过请求(Request)过来的参数与策略通过规则进行匹配获得一个影响(Effect),拿到影响的结果,进到影响的表达式,返回一个布尔值

PERM(Policy Effect Request Matchers)

  • subject: sub 访问实体

  • object: obj 访问的资源

  • action: act 访问方法

  • eft: eft 策略结果,一般为空,默认指定allow,还可以定义为deny(拒绝)(只有这两种结果)

Policy策略

一般存储到数据库

p = {sub, obj, act, eft}

[policy_definition]
p = sub,obj,act

Matchers 匹配规则

Request和Policy的匹配规则

m = r.sub == p.sub && r.act == p.act && r.obj == p.obj

Effect 影响

支持的Policy effects如下:

Policy effect意义
some(where (p.eft == allow))只要有一个allow就通过
!some(where (p.eft == deny))没有deny就通过
some(where (p.eft == allow)) && !some(where (p.eft == deny))有allow并且没有deny通过
priority(p.eft) || denypriority
subjectPriority(p.eft)基于角色的优先级

Request 请求

r = {sub, obj, act}

ACL

[request_definition]
r = sub, obj, act

[policy_definition]
p = sub, obj, act // 这里不加 ', eft'的话,police_effect就没有用到

[policy_effect]
e = some(where (p.eft == allow))

[matchers]
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act
p, alice, data1, read
p, bob, data2, write
alice, data1, read
true

RBAC

单商户模型

和ACL模型相比,多了一个[role_definition] g后面的两个横线,一个表示用户,一个表示角色,

在[matchers]中,也有了g(r.sub, p.sub)

[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
p, alice, data1, read
p, bob, data2, write
p, data2_admin, data2, read
p, data2_admin, data2, write

g, alice, data2_admin

Policy最后一行,用户alice有作为data2_admin角色,感觉就像是alice他有另一个马甲,叫做data2_admin,这两个都是它的身份,像一个人,他既是作为游戏开发者,也是作为玩家,这两个都是它的身份,而他既能行驶玩家的权限,游玩游戏,又能作为开发者,修改自己游戏的数据。

alice, data2, read
true

RBAC with domains/tenants

多商户模型

与单商户模型相比,又多了一个domains

在[request_definition],[policy_definition]中,都多出来了一个dom

[role_definition]多出一条横线

[request_definition]
r = sub, dom, obj, act

[policy_definition]
p = sub, dom, obj, act

[role_definition]
g = _, _, _

[policy_effect]
e = some(where (p.eft == allow))

[matchers]
m = g(r.sub, p.sub, r.dom) && r.dom == p.dom && r.obj == p.obj && r.act == p.act
p, admin, domain1, data1, read
p, admin, domain1, data1, write
p, admin, domain2, data2, read
p, admin, domain2, data2, write

g, alice, admin, domain1
g, bob, admin, domain2

对于domain(域)我的理解是,

像一个人,他是一个游戏玩家,还是一个游戏开发者,在电脑上(domain1),他可以行驶游戏角色的权利,对其他角色发起攻击,他也行驶游戏开发者的权利,修改自己角色数值。离开了电脑,到现实世界(domain2),他作为游戏玩家,什么都做不了,但作为游戏开发者,他有领取薪水的权利

alice, domain1, data1, read
true
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

casbin学习笔记 的相关文章

  • 力扣网页PC端无法进入(问题得到解决)

    最近发现在不同地方 xff0c 使用不同WiFi时 xff0c 有些地点出现力扣网页PC端无法加载的问题 按照网上方法进行了调试 xff0c 发现帖子推荐改hosts文件 xff0c 将自己电脑https leetcode cn com 的
  • Linux临时动态调整kvm虚拟机内存

    一 运维内容描述 同事反馈在用的虚拟机内存不足 xff0c 需要调整 查看一个虚拟机的内存情况 xff0c 最大是8G内存 xff0c 当前内存显示是4G 虚拟机调整最大内存是需要关闭虚拟机的 xff0c 但现在虚拟机上部了服务 xff0c
  • stringstream的用法

    1 用stringstream来分割指定的字符字符串 xff0c 代码如下 xff1a span class token comment 用stringstream来分割指定的字符字符串 span span class token macr
  • C++字符串输入问题

    经常写核心代码模式 xff0c 对于输入输出很多情况下 xff0c 不怎么会写了 所以 xff0c 做个总结 对于如下输入 xff1a span class token comment 输入 xff1a span span class to
  • 中国系统面试0819

    一面 xff1a 30min C 43 43 xff1a 1 C 43 43 的三大特性 xff0c 以及在项目中是如何是用到的 xff08 封装 继承 多态 xff09 2 STL了解哪些 xff0c 在项目中如何使用的 xff0c 举例
  • C语言实现多态

    利用C语言实现多态 xff1a c语言多态的实现 xff0c 需要用到函数指针 函数名实际上是该函数代码存储空间的首地址 xff0c 这个地址可以通过函数指针来存放 通过改变函数指针存储的地址就可以实现多态 span class token
  • 深入浅析Mysql联合索引原理 之 最左匹配原则。

    前言 之前在网上看到过很多关于mysql联合索引最左前缀匹配的文章 xff0c 自以为就了解了其原理 xff0c 最近面试时和大牛交流中 xff0c 发现遗漏了些东西 xff0c 这里自己整理一下这方面的内容 最左前缀匹配原则 在mysql
  • kubernetes Value:将磁盘挂载到容器,PV,PVC

    6 1 介绍卷 6 1 1 卷的类型 emptyDir 用于存储临时数据的简单空目录 hostPath 用于将目录从工作节点的文件系统挂载到pod nfs 挂载到pod中的NFS共享卷 还有其他的如gitRepo gcepersistenD
  • 记一次容器内执行ansible命令卡住

    1 由来 最近在使用kylin v10系统 xff0c 发现当在此系统下运行的容器内执行 ansible localhost m setup 命令会卡住不动 xff0c 于是和同事一起经过如下排查最终找到解决问题的办法 2 环境 2 1 系
  • k8s pod报错Process failed to launch spawn E2BIG

    一 问题描述 近期遇到k8s环境中一个pod无法正常启动 xff0c 启动报错 xff0c PM2 ERROR Process failed to launch spawn E2BIG 二 问题分析 2 1 了解报错相关知识 查阅资料发现
  • 通过TCP Allocate连接数告警了解prometheus-NodeExporter数据采集及相关知识扩散

    1 问题由来 近日有环境告警如下 xff1a TCP Allocate连接数过多 很多资料告诉我们使用 netstat ant grep tcp wc l命令查询 xff0c 但查询的值与告警中获取的只相差很大 xff0c 于是下载Node
  • OpenStack是什么,OpenStack详解

    1 OpenStack是什么 OpenStack官方的解释很官方 xff0c 而且从不同角度 xff0c 也有不同的理解 xff0c OpenStack可以理解为一个云操作系统 OpenStack旗下包含了一组由社区维护的开源项目 xff0
  • Vue+dataV:调用后台数据,数据赋值成功,但是组件上的数据更新失败

    问题描述 公司要做个数据看板 xff0c 因为在项目中应用到了dataV xff0c 在使用的过程中 xff0c 发现dataV的组件的数据 xff0c 若是来自自己定义的常量数据 xff0c 数据可以正常显示在组件中 但当数据来自于axi
  • Windows Server 2008搭建域控制器

    前言 1 为什么要建域 工作组的分散管理模式不适合大型的网络环境下工作 xff0c 域模式就是针对大型的网络管理需求设计的 xff0c 就是共享用户账号 xff0c 计算机账号和安全策略的计算机集合 域中集中存储用户账号的计算机就是域控器
  • -bash: zip: command not found提示解决办法

    bash zip command not found 是因为liunx服务器上没有安装zip命令 xff0c 需要安装一下即可 linux安装zip命令 xff1a apt get install zip 或yum install zip
  • 超全的数据库分类介绍

    数据库的分类 数据库通常分为层次式数据库 网络式数据库和关系式数据库三种 而不同的数据库是按不同的数据结构来联系和组织的 而在当今的互联网中 xff0c 最常见的数据库模型主要是两种 xff0c 即关系型数据库和非关系型数据库 数据库分类
  • suse11/12关闭防火墙

    suse11 关闭操作为 xff1a service SuSEfirewall2 setup stop service SuSEfirewall2 init stop 取消开机启动防火墙 xff1a chkconfig SuSEfirewa
  • pip download 只下载不安装命令的使用方法

    比如下载 django 1 8 11版本和simplejson 3 14 0版本的包 那么就将所需的包写入 requirement txt 那么我的requirement txt内容就是 xff1a django 61 61 1 8 11
  • k8s学习笔记

    九 deployment xff1a 声明式的升级应用 9 1 使用RC实现滚动升级 kubectl rolling update kubia v1 kubia v2 image 61 luksa kubia v2 使用kubia v2版本
  • k8s学习笔记---Statefulset:部署有状态的多副本应用

    10 1 什么是Statefulset StatefulSet是Kubernetes提供的管理有状态应用的负载管理控制器API 特点 xff1a 1 具有固定的网络标记 xff08 主机名 xff09 2 具有持久化存储 3 需要按顺序部署

随机推荐