小工具      在线工具  汉语词典  dos游戏  css  js  c++  java

casbin轻量级的基于配置的授权框架

# 中间件,golang,casbin 额外说明

收录于:17天前

简介

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

Casbin 提供了一个执行器,用于根据提供给执行器的策略和模型文件验证传入请求。然后,根据相应的配置授权策略,验证请求决定发布哪些动作。

在Casbin中,访问控制模型被抽象为基于PERM(Policy、Effect、Request、Matcher)的配置文件。 PERM模式由四个基础(策略、效果、请求、匹配)组成,描述了资源和用户之间的关系。通过配置文件对用户进行授权,可以更方便地更改和迭代授权系统。

Casbin使用配置文件来设置访问控制模式。

工作原理

访问控制模型PERM是casbin的权限机制。它通过四个对象来描述资源的关系:Policy、Effect、Request、Matcher。

定义请求参数。一个基本请求是一个元组对象,它至少需要访问实体(Subject)、访问资源(Object)和访问方法(Action)。

请求是一个访问承载对象,承载着用户的访问权限。

r = sub, obj, act

战略

策略部分中的每一行称为策略规则。每个策略规则通常以 p、p2 形式的策略类型开始。策略定义匹配模式。不同的模式需要满足不同的匹配规则。

p = sub, obj, act
p2 = sub, act

规则

匹配请求和匹配策略的比较规则。不同的匹配策略有不同的比较方法。

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

策略中定义了两种匹配模式p和p2,匹配规则中定义了请求与p策略的比较规则。

影响

效果是对匹配结果的判断。

e = some (where (p.eft == allow))

匹配策略p没有定义匹配结果eft,但是每个匹配规则都会默认有一个匹配结果。

这些规则的定义都是casbin支持的访问控制模型。这个模型的名称叫ACL。另外casbin还支持其他很多模型如RBAC,ABAC等。

一个完整的ACL模型如下:

# casbin请求格式
[request_definition]
r = sub, obj, act

# casbin策略模式
[policy_definition]
p = sub, obj, act
p2 = sub, act

# casbin测率匹配结果
[policy_effect]
e = some(where (p.eft == allow))

# casbin率略匹配规则
[matchers]
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act

[request_definition]类似定义是声明请求等对象不可缺少。在ACL模型中至少需要访问实体(Subject)、访问资源(Object) 和访问方式(Action)。命名不仅限于sub,obj,act,只要请求和策略和匹配对应即可。

上述ACL模型的含义是将sub、obj、act定义为匹配对象的p策略;定义的请求p需要按照策略的格式携带参数;定义匹配规则m,用于将请求参数与请求策略进行匹配;最好返回匹配结果 e 。

这些过程都是由casbin框架独立完成的。只需要使用casbin提供的接口,按照规则传入参数,得到匹配结果。不过这些访问控制的规则是需要定义的,因为官方提供了很多规则模型,开发者需要自己选择合适的模型。

规则模型定义子在conf文件中,model.conf:

# casbin请求格式
[request_definition]
r = sub, obj, act

# casbin策略模式
[policy_definition]
p = sub, obj, act
p2 = sub, act

# casbin测率匹配结果
[policy_effect]
e = some(where (p.eft == allow))

# casbin率略匹配规则
[matchers]
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act

在这里插入图片描述

政策授权

既然已经定义了访问控制模型,就需要定义具体的用户授权。此步骤是将实际用户与匹配规则关联起来。

casbin使用配置来控制访问权限,授权机制使用csv文件。police.csv

p,xiaoxu,data1,read
p,zhangsan,data2,write

上述匹配规则下的p模式下,xiaoxu用户可以访问data1,读取访问限制; zhangsan用户可以访问data2,访问权限为write。

案例

简单案例
在这里插入图片描述

主要功能如下:

package main

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

func main() {
    
	e, err := casbin.NewEnforcer("model.conf", "policy.csv")
	if err != nil {
    
		println(err)
		return
	}
	enforce, err := e.Enforce("xiaoxu", "data1", "read")
	if err != nil {
    
		println(err)
	}
	fmt.Println("访问权限结果", enforce)

}

casbin.NewEnforcer()方法加载模型和授权策略,返回casbin.Enforcer对象,改对象的e.Enforce方法传入用户的请求,返回是否有访问权限。

main函数的执行结果为true,表示"xiaoxu", “data1”, "read"满足匹配策略有访问权限。
在这里插入图片描述

如果修改了用户名,导致policy.csv中没有对应的配置,则会返回false,表示没有权限访问。

Gin框架中间件集成casbin

package main

import (
	"github.com/casbin/casbin/v2"
	"github.com/gin-gonic/gin"
)

func main() {
    
	/* e, err := casbin.NewEnforcer("model.conf", "policy.csv") if err != nil { println(err) return } enforce, err := e.Enforce("xiaoxu1", "data1", "read") if err != nil { println(err) } fmt.Println("访问权限结果", enforce) */
	
	//gin路由

	engine := gin.Default()
	engine.GET("/data1", casbinAuth(), func(context *gin.Context) {
    
		context.String(200, "data1")
	})
	engine.GET("/data2", casbinAuth(), func(context *gin.Context) {
    
		context.String(200, "data2")
	})
	engine.GET("/data3", casbinAuth(), func(context *gin.Context) {
    
		context.String(200, "data3")
	})

	engine.Run("127.0.0.1:8080")
}

//定义权限中间件

func casbinAuth() gin.HandlerFunc {
    
	return func(context *gin.Context) {
    
		var req CasbinRequest
		context.ShouldBindJSON(&req)
		if casBin(req.Sub, req.Obj, req.Act) {
    
			context.Next()
		} else {
    
			context.Next()
			context.String(503, "没有权限访问!")
		}
	}
}

//定义casbin模型

func casBin(sub, obj, act string) bool {
    
	e, err := casbin.NewEnforcer("model.conf", "policy.csv")
	if err != nil {
    
		println(err)
		return false
	}
	enforce, err := e.Enforce(sub, obj, act)
	if err != nil {
    
		println(err)
		return false
	}
	return enforce
}

type CasbinRequest struct {
    
	Sub  string `json:"sub"`
	Obj  string `json:"obj"`
	Act  string `json:"act"`
	Data string `json:"data"`
}

请添加图片描述

通过gin的中间价格调用casbin方法来判断是否有访问权限。

修改权限配置如下:

p,xiaoxu,data1,read
p,xiaoxu,data1,write

p,xiaoxu,data2,write

p,xiaoxu,data3,read


p,zhangsan,data2,read
p,zhangsan,data3,read

请添加图片描述

在实际项目中,policy.csv的配置显然是不合适的。在Web项目中,权限对应的是API接口,因此需要匹配当前地址来判断用户权限。

在上面权限验证的过程中忽略了一个问题,就是casbin.NewEnforcer是验证式策略,只要plicy.csv中配置存在就会返回true,那么将Sub看作用户,Obj看作资源,Act看作接口即可实现权限配置。如下重构的代码:

package main

import (
	"github.com/casbin/casbin/v2"
	"github.com/gin-gonic/gin"
	"strings"
)

func main() {
    
	engine := gin.Default()
	engine.GET("/data1/list", casbinAuth(), func(context *gin.Context) {
    
		context.String(200, " data1 list ...")
	})
	engine.GET("/data1/add", casbinAuth(), func(context *gin.Context) {
    
		context.String(200, "data1 add ...")
	})
	engine.GET("/data1/delete", casbinAuth(), func(context *gin.Context) {
    
		context.String(200, "data1 delete ...")
	})
	engine.GET("/data1/update", casbinAuth(), func(context *gin.Context) {
    
		context.String(200, "data1 update ...")
	})
	engine.GET("/data2/list", casbinAuth(), func(context *gin.Context) {
    
		context.String(200, "data2 list ...")
	})
	engine.GET("/data2/add", casbinAuth(), func(context *gin.Context) {
    
		context.String(200, "data2 add ...")
	})
	engine.GET("/data2/delete", casbinAuth(), func(context *gin.Context) {
    
		context.String(200, "data2 delete ...")
	})
	engine.GET("/data2/update", casbinAuth(), func(context *gin.Context) {
    
		context.String(200, "data2 update ...")
	})

	engine.Run("127.0.0.1:8080")
}

//定义权限中间件

func casbinAuth() gin.HandlerFunc {
    
	return func(context *gin.Context) {
    
		var req Username
		context.ShouldBindJSON(&req)
		//获取路径地址
		path := context.FullPath()
		split := strings.Split(path, "/")
		//fmt.Println(split)
		sub := req.Username
		obj := split[1] //请求的资源
		act := split[2] //请求资源的权限
		//
		if casBin(sub, obj, act) {
    
			context.Next()
		} else {
    
			context.Next()
			context.String(503, "没有权限访问!")
		}
	}
}

//定义casbin模型

func casBin(sub, obj, act string) bool {
    
	e, err := casbin.NewEnforcer("model.conf", "policy.csv")
	if err != nil {
    
		println(err)
		return false
	}
	enforce, err := e.Enforce(sub, obj, act)
	if err != nil {
    
		println(err)
		return false
	}
	return enforce
}

type Username struct {
    
	Username string `json:"username"`
}

政策.csv如下:

p,xiaoxu,data1,list
p,xiaoxu,data1,add
p,xiaoxu,data1,delete
p,xiaoxu,data1,update


p,zhangsan,data1,list
p,zhangsan,data1,add

p,list,data2,list
p,list,data2,add
p,list,data2,delete
p,list,data2,update

data1的类似配置就是配置资源,add等代表增删改查的动作,也代表uil地址。以上配置赋予了xiaoxu所有的增删改查权限。用户zhansan只有查看和添加的权限,list拥有data2资源的所有权限。

重构后的代码如下:

请添加图片描述

用户权限的配置不仅限于policy.csv文件配置,还可以使用数据库。

新建Casbin enforcer的时候 你必须提供一个 Model 和一个 Adapter。model就是model.conf,Adapter默认是 FileAdapter。如果要是hi用数据库就需要更改适配器。

更改适配器官方文档

casbin官方文档

教程文档

. . .

相关推荐

额外说明

ELK与EFK的关系、区别及发展历史

ELK与EFK的关系与区别 ELK和EFK都是用于实时搜索、分析和可视化大规模数据的解决方案,它们的组件和功能有许多相似之处,但也存在一些细微的区别。 关系 ELK(Elasticsearch、Logstash、Kibana)和EFK(Elasticse

额外说明

【Python面向对象编程】第十九章 只读属性

本文我们介绍如何定义 Python 只读属性,以及使用只读属性定义计算属性。 只读属性简介 定义只读属性的方法就是创建只有 getter 方法的属性。不过,这种方法定义的不是真正意义上的只读属性,因为我们总是可以访问和修改底层的属性。 只读属性通常用于某

额外说明

《PostgreSQL开发指南》第二十九章 Python访问PostgreSQL

《PostgreSQL 开发指南》专栏目录 第 01 篇 课程介绍 第 02 篇 PostgreSQL 简介 第 03 篇 PostgreSQL 安装 第 04 篇 角色与用户 第 05 篇 数据库与模式 第 06 篇 管理数据表 第 07 篇 管理表空

额外说明

.c 求水仙花数

参考如下: #include <stdio.h> int main() { int waternum; printf("三位数中 水仙花数有:"); for (waternum = 100;waternum <= 999;waternum++){

额外说明

Zookeeper 源码分析--Zookeeper启动流程(一)

Zookeeper 源码分析–Zookeeper启动流程(一) 最近学习了一下Zookeeper,怎么说呢,总起来就学到了两个概念性的名词,当然这两个名词均和一个Zookeeper的协议相关,那就是ZAB协议,来名词呈上来:崩溃恢复和消息广播。但是俗话说

额外说明

Java实现对称加密(DES,AES)快速入门示例

对称加密是使用相同的密码进行加密和解密, 对称加密实现简单,安全性相比非对称加密较弱, 常用的对称加密算法有 DES,AES以及PDE等,关于对称加密相关概念参考: 对称加密、非对称加密深度解析 本篇介绍Java的DES和AES的加密和解密, 关于PDE

额外说明

ExtJS+SpringBoot实现读取后端数据的树

关于Ext JS树的基本使用可以参考:[Ext JS] 3.3 树(Tree)的定义和使用,本篇示例主要介绍基于Spring Boot使用后端数据的树, 以及展开某个节点, 以及定位节点。 后端定义 后端定义数据节点的模型类Node, 对应Ext JS

额外说明

handlebars.js模版引擎中EACH循环遍历的使用

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.js"></s

额外说明

HLA程序:HelloWorld.hla

HLA程序:HelloWorld 教材:《汇编语言编程艺术》 1、下载hla,安装到d:\hla,并在环境变量中设置好路径。 2、在d盘创建一个文件夹myhla,用于存放hla源程序。 3、在myhla里创建一个HelloWorld.hla程序 prog

额外说明

mybatis逆向工程

超级简单的逆向工程 导入坐标 创建配置文件 创建java类 测试运行 导入坐标 所使用的是1.3.5版本的jar <!-- 逆向工程的jar--> <dependency> <groupId>org.mybatis.generator</grou

ads via 小工具