Casbin的使用实例

Casbin

帮助文档地址:https://casbin.org/docs/zh-CN/how-it-works

常见的设计模式(DAC,MAC,RBAC,ABAC)

0.基于权限的角色控制 RBAC

1.基于属性的权限验证(ABAC: Attribute-Based Access Control)

创建一个Casbin决策器需要有一个模型文件和策略文件为参数:

特性:

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

Casbin不执行的操作:

  1. 身份验证(又名验证username以及password用户登录时)
  2. 管理用户或角色列表。我相信项目本身管理这些实体会更方便。用户通常具有其密码,而Casbin并非设计为密码容器。但是,Casbin存储RBAC方案的用户角色映射。

模型文件:model.conf

# Request definition
[request_definition] 自定义请求的格式
r = sub, obj, act
 
# Policy definition
[policy_definition] 策略定义
p = sub, obj, act
 
# Policy effect
[policy_effect]
e = some(where (p.eft == allow))
 
# Matchers
[matchers]
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act

&& (r.act == p.act || p.act == “")//注意最后一行的p.act="”,这个意思是说忽略客户端浏览器发起的请求类型,即不分辨GET、POST、FETCH等http方法。

采用本地csv格式的Demo

策略文件:

p, superAdmin, project, read
p, superAdmin, project, write
p, admin, project, read
p, admin, project, write
p, admin, asse, read
p, admin, asse, write
p, zhuangjia, project, write
p, zhuangjia, asse, write
p, shangshang, project, read
p, shangshang, asse, read

g, quyuan, admin
g, wenyin, zhuangjia

main文件

package main

import (
	"fmt"
	"log"

	"github.com/casbin/casbin"
)

func main() {
	TestRBAC()
}

func TestRBAC() {
	e, _ := casbin.NewEnforcer("rbac_model.conf", "rbac.csv")
	fmt.Printf("RBAC test start\n") // output for debug

	// superAdmin
	if aa, err := e.Enforce("superAdmin", "project", "read"); err == nil {
		if aa {
			log.Println("superAdmin can read project")
		}else{
			log.Fatal("ERROR: superAdmin can not read project")
		}
	} else {
		fmt.Println("err1", err)
	}
	
}

采用读取数据方式的Demo

策略文件:casbin_rule.sql

表有,ptype,v0,v1,v2,v3,v4,v5.目前只使用到ptype,v0,v1,v2

ptype写死为p,v0为角色,v1为操作路径v2为方式,如:例如ptype:p,v0:admin,v1:/api/v1/aa,v2:GET

/*
Navicat MySQL Data Transfer

Source Server         : 192.168.10.203
Source Server Version : 50646
Source Host           : 192.168.10.203:3306
Source Database       : wingo_dev

Target Server Type    : MYSQL
Target Server Version : 50646
File Encoding         : 65001

Date: 2020-07-14 10:02:17
*/

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for `casbin_rule`
-- ----------------------------
DROP TABLE IF EXISTS `casbin_rule`;
CREATE TABLE `casbin_rule` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `p_type` varchar(255) NOT NULL,
  `v0` varchar(255) NOT NULL,
  `v1` varchar(255) NOT NULL,
  `v2` varchar(255) NOT NULL,
  `v3` varchar(255) NOT NULL,
  `v4` varchar(255) NOT NULL,
  `v5` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of casbin_rule
-- ----------------------------
package main

import (
	"fmt"
	"net/http"

	"github.com/casbin/casbin"
	"github.com/casbin/gorm-adapter"
	"github.com/gin-gonic/gin"
	_ "github.com/go-sql-driver/mysql"
)

func main() {

	a, err := gormadapter.NewAdapter("mysql", "root:123456@tcp(192.168.10.203:3306)/test_casbin", true)
	if err != nil {
		fmt.Println("NewAdapter", err)
	}
	//创建一个Casbin决策器需要有一个模型文件和策略文件为参数:
	e, err := casbin.NewEnforcer("rbac_model.conf", a)
	if err != nil {
		fmt.Println("NewEnforcer", err)
	}
	//从DB加载策略
	e.LoadPolicy()

	//获取router路由对象
	r := gin.New()
	//使用自定义拦截器中间件
	r.Use(LanjieqiHandler(e))
	//创建请求
	r.GET("/api/v1/aa", func(c *gin.Context) {
		var message string = "成功"
		var code int = 200
		var aa string = "data"
		c.JSON(http.StatusOK, gin.H{
			"code":    code,
			"message": message,
			"data":    aa,
			"result":  "true",
		})
	})

	r.Run(":9090") //参数为空 默认监听8080端口
}

//拦截器
//拦截器
func LanjieqiHandler(e *casbin.Enforcer) gin.HandlerFunc {

	return func(c *gin.Context) {

		//获取请求的URI
		obj := c.Request.URL.RequestURI()
		//获取请求方法
		act := c.Request.Method
		//获取用户的角色
		sub := "admin"

		//判断策略中是否存在
		aa, err := e.Enforce(sub, obj, act)
		if err != nil {
			fmt.Println("e.Enforce error")
		}
		if aa {
			fmt.Println("通过权限")
			c.Next()
		} else {
			fmt.Println("权限没有通过")
			c.Abort()
		}
	}
}
访问地址:http://127.0.0.1:9090/api/v1/aa
返回结果:{"code":200,"data":"data","message":"成功","result":"true"}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值