beego利用casbin进行权限管理——第四节 策略更新

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hotqin888/article/details/80032538

近4个月没有更新这个系列。这个系列都是我粗浅的理解,其中我感觉有些的思路并非最优,并不合主流概念,因为我没去学习rbac之类的概念,仅供参考。特别是对于权限设计的处理方式,casbin是尽量用它自己的查询方式,因为那是直接查(增、删、改)内存(map),而不应该去查(增、删、改)数据库,这点必须避免,这个系列文章中很多犯这样的错误,阅读时,应该根据自己的场景,去回避犯这种错误。

这次后半部分借助我刚写完的onlyoffice的权限设计,这个权限设计总体感觉蛮新颖的,是仿照onlyoffice community写的,对文档的赋权,无论是用户还是角色,每个对应4种权限,一气呵成,我使用bootstrap table的x-editable以及select2等进行下拉选择,实时批量设置和单独切换权限,非常自由随性。

策略更新包含用户角色更新,用户或角色的权限更新。casbin的rbac_api.go和management_api.go中的方法,似乎分成几个“层次”:比如addrole和addpermission,这种专用的;AddNamedPolicy类似这种通用的。

再比如GetPermissionsForUser,它不同于enforce(),后者能够实现:user属于role,user具备访问data1的权限,role具备访问data2的权限,此时用enforce(user,data2),结果是true,但是用GetPermissionsForUser(user),它取不到role的data2。 只能用 先取出user的所有角色,再循环,取出每个角色具备的权限。   

  roles := e.GetRolesForUser(useridstring) //取出用户的所有角色
					for _, w := range roles {
						roleRes = e.GetPermissionsForUser(w) //取出角色的所有权限
						for _, k := range roleRes {

言归正传,策略修改总的思路应该是这样:

1.要更新一个用户的角色,先把这个用户的角色全部删掉,然后重新添加这个用户的角色。

2.更新用户(或角色)的权限,先把这个用户对于某个文件的权限全部删掉,再重新添加,道理一样。

首先是用户和角色的修改:下图,点击用户,下面显示这个用户具有的角色,并勾选上。

当修改勾选后,再保存,后端先用e.DeleteRolesForUser(uid)将这个用户的所有角色删除。再根据前段选中的传入后端进行循环添加。

//添加用户角色
//先删除用户所有角色
func (c *RoleController) UserRole() {
	//要支持批量分配角色,循环用户id
	uid := c.GetString("uid") //secofficeid
	//先删除用户的权限
	e.DeleteRolesForUser(uid) //数据库没有删掉!
	//删除数据库中角色中的用户
	//o := orm.NewOrm()
	//qs := o.QueryTable("casbin_rule")
	//_, err := qs.Filter("PType", "g").Filter("v0", uid).Delete()
	//if err != nil {
	//	beego.Error(err)
	//}
	//再添加,如果没有选择,相当于删除了全部角色
	ids := c.GetString("ids") //roleid
	if ids != "" {
		array := strings.Split(ids, ",")
		for _, v1 := range array {
		e.AddGroupingPolicy(uid, "role_"+v1) 
			//应该用AddRoleForUser()//rbac_api.go
		}
		
	}
	c.Data["json"] = "ok"
	c.ServeJSON()
}

onlyoffice中对于某个文档的权限更新

选中一个文档,点击权限按钮,显示这个文档的用户、角色和对应的权限。

用casbin的users := e.GetFilteredPolicy(1, "/onlyoffice/"+strconv.FormatInt(w.Id, 10))

GetFilteredPolicy支持多字段查询:e.GetFilteredPolicy(1, "/onlyoffice/"+strconv.FormatInt(w.Id, 10),"3")

对于/onlyoffice/26这个文档,当删除或增加用户、角色后,传到后台,先用RemoveFilteredPolicy删掉所有的CasbinRul表中v1为/onlyoffice/26的策略。 RemoveFilteredPolicy支持多字段,如: RemoveFilteredPolicy(1, action.URL, action.Method)这样就是把  所有action.URL  以 action.Method 方法访问的 plicy 全部删掉了。

然后再根据传过来的策略重新存入。因为这里是把用户和角色放在一个表格里,所以要做一下区分,角色id加上role_字样,以示区别。

	e.RemoveFilteredPolicy(1, "/onlyoffice/"+strconv.FormatInt(attachments[0].Id, 10))

//o := orm.NewOrm()
	//qs := o.QueryTable("casbin_rule")
	//_, err = qs.Filter("v1", "/onlyoffice/"+strconv.FormatInt(attachments[0].Id, 10)).Delete()
	//if err != nil {
	//	beego.Error(err)
	//}
//再添加permission
	for _, v1 := range rolepermission {
		// beego.Info(v1.Id)
		if v1.Rolenumber != "" { //存储角色id
			success = e.AddPolicy("role_"+strconv.FormatInt(v1.Id, 10), "/onlyoffice/"+strconv.FormatInt(attachments[0].Id, 10), v1.Permission, suf)
		} else { //存储用户id
			success = e.AddPolicy(strconv.FormatInt(v1.Id, 10), "/onlyoffice/"+strconv.FormatInt(attachments[0].Id, 10), v1.Permission, suf)
		}
		//这里应该用AddPermissionForUser(),来自casbin\rbac_api.go
	}

RemovePolicy和RemoveGroupingPolicy可以根据自己的场景来使用。

上面例子,本来用casbin的方法,删除了内存中的策略,相应的它会自动删除数据库中的数据,但是暂时解决不了,导致数据库的数据不会自动删除,所以分别添加了一段代码,用于删除数据库数据。

casbin用于判断用户的的权限是很方便的。但由于场景很多,比如有时候要显示一个登录用户对各个资源的的权限(下图):

有时管理员要知道一个资源所有的用户和角色,并对应拥有的权限,如下图。这里应该用management_api.go中GetFilteredPolicy之类的方法从内存中获取,而不应该像我的代码里那样,从数据库获取,注意。

users := e.GetFilteredPolicy(1, "/onlyoffice/"+strconv.FormatInt(w.Id, 10))
		// beego.Info(users)
		for _, v := range users {
			rolepermission1 := make([]Rolepermission, 1)
			if strings.Contains(v[0], "role_") { //是角色
				// beego.Info(v.V0)
				roleid := strings.Replace(v[0], "role_", "", -1)

还有个几个常见的问题:

1.用户的权限permission(action)用1、2、3、4来表示还是用get,post,……因为有时候要分等级和优先,如果再加一个字段不一定需要。比如,对于一个文档,全部权限规定为1,评论为2,只读为3,不允许为4。设置权限的时候,直接给这个用户设置权限为只读3,而这个用户属于角色role,这个role对这个文档权限是1,那这个用户应该是最大权限优先。所以用1234比较合适,转成int后可以做比对,取最小的。

2.casbin对于admin应该没有特殊的处理吧,和普通角色一样来设置吧。

3.另外casbin对于ip区段支持。这个我以前还在网上找了一段ip区段处理的代码,好像是某个ip扫描器代码,先把区段变成一个个ip,对应端口号,然后写入map,在内存中。竟然类似casbin的方式。

接下来有个不成熟的想法:把casbin的example里的conf和csv一一对应地放到一个文件中,加上注释,可能的话配上增删改等方法。这样方便初学者能够直接进入例子,或者自己的场景能直接在这里找到例子。另外就是一些casbin的思想,我都是东拼西凑理解的,并非代表官方思路,它的处理手段背后为啥要这样?

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏挖坑填坑

(翻译)开始使用ABP.CORE模板 (ASP.NET Core with Angular)

开始一个新使用Angular和 ASP.NET Core 的ABP项目最简单的方法就是通过官方的模板页面来生成模板。切记包含zero模块。在官网完成创建和下载你...

27120
来自专栏西安-晁州

Xss和Csrf介绍

Xss和Csrf介绍 Xss Xss(跨站脚本攻击),全称Cross Site Scripting,恶意攻击者向web页面中植入恶意js代码,当用户浏览到该页时...

38290
来自专栏IMWeb前端团队

浅析YSlow-23条规则

本文作者:IMWeb 孙世吉 原文出处:IMWeb社区 未经同意,禁止转载 起因 起初想要去了解如何提高网页加载性能,发现Yahoo发布的一款基于Fi...

23970
来自专栏糊一笑

如何在IOS上调试Hybrid应用

最近在找关于在xcode上调试Hybrid应用的方法,比如我想进行断点调试、日志打印已经屏幕适配等等,刻意去搜了下方法,虽然之前已经大致知道了,这里系统归纳一下...

35160
来自专栏一“技”之长

分分钟搞定IOS远程消息推送 原

IOS中消息的推送有两种方式,分别是本地推送和远程推送,本地推送在http://my.oschina.net/u/2340880/blog/405491这篇博客...

10310
来自专栏游戏杂谈

前端开发--优化工具

一般来讲优化前端,涉及到文件优化的有合并、压缩JS和CSS,以及对图片的优化处理,这篇文章的工具很不错,强烈推荐一下。

14830
来自专栏coding for love

从输入url到看到页面的过程分析

我思考了很多知识组织方法来帮助理解网络知识,比如按osi模型从底至上,或者按协议种类,或者按网络发展史。但最终我还是决定选择用这个经典的问题,将网络知识串成线。...

14220
来自专栏用户2442861的专栏

Chrome开发者工具不完全指南(二、进阶篇)

上篇向大家介绍完了基础功能篇,这次分享的是Chrome开发工具中最有用的面板Sources。  Sources面板几乎是我最常用到的Chrome功能面板,也是...

11510
来自专栏王磊的博客

逻辑性最强的React Native环境搭建与调试

ReactNative系列文章: 1.《逻辑性最强的React Native环境搭建与调试》 2.《ReactNative开发工具有这一篇足矣》 正文 Reac...

30170
来自专栏腾讯NEXT学位

小程序iOS客户端框架——控件事件逻辑框架与控件原生化(上)

? 小程序自发布以来,为开发者和用户提供了一种轻量级的App。作为一种不需要下载安装即可使用的应用,它实现了应用“触手可及”的梦想,用户扫一扫或者搜一下即可打...

22010

扫码关注云+社区

领取腾讯云代金券