权限模型以及常见实现方式

权限模型以及常见实现方式

三种权限模型简介

ACL模型

该模型基于用户的权限管理模型(ACL, Access Control List)

基于用户的概念就是说直接对用户进行权限分配管理,好处是模型构建简单,只需要给用户授予或者取消对应权限即可。但是相对的,如果用户数量庞大的情况下,这套模型就很不实用。因为需要对每一位用户对应权限进行维护,这导致维护成本太高。

ACL模型表结构很简单,只需要用户user表和权限节点node以及user和node的多对多关系表user_node。同时,只需要维护user_node表中user和node关系即可。

ACL的适用于用户数量较小的管理系统中,例如:1班有40位同学,张三拥有班长权限、李四拥有学委权限、王五拥有纪委权限,其它同学只拥有普通权限。

在ACL权限模型下,权限管理是围绕资源来设定的。

RABC模型

该模型是基于角色的权限管理模型(RBAC, Role Based Access Control)

角色的概念就是对用户的一个升级,管理者不需要考虑用户和权限关系。只需要给用户某种角色,然后对角色授予或者取消对应权限。模型构建相对复杂,但是在用户数量大的情况下,还是需要维护角色和权限关系,以及用户和角色关系。

RBAC的表结构包括,用户user表、角色role表、权限节点node表和用户user和角色role多对多关系的user_role表及角色role和节点多对多关系的role_node表,共5张表。

ABAC 模型

该模型基于属性的权限管理模型(ABAC, Attribute Based Access Control)

ABAC对用户本身的属性进行标识,通过标识来判断用户权限。这样的设计使得ABAC非常灵活,可扩展性也很高。

ABAC一般来说,都是搭配着ACL或RBAC一起使用,不会单独成体系。在设计中,只需要在user表中加入对应字段即可,例如:某平台只允许25到50岁之间的用户注册,那么需要在user表中加入age字段。

它相对于RABC模型多了一张表,如果将属性表看做角色表,那么就是多了一张绕过角色的用户权限关系表user_node。

三大模型总结

这三种权限管理模型,也可以说是设计理念;

在web后端的开发中都是以用户为主体,构建起来都较为简单。

当然,它们各自都有优缺,只是两权相难取其轻,具体开发过程中还需要权衡开发成本而选择。

django项目auth群表

django项目默认的配置就是采取的RABC的权限策略,用户与组之间有多对多的关系,组与权限之间有多对多的关系,通过django-admin后台管理就可以快速的实现。

casbin概述

——》》》casbin官方文档

casbin支持的语言十分的多,对python更是做到了各种权限模型的实现。

用casbin开始建立权限模型

配置文件:

# conf文件model.conf
[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

# 权限策略文件policy.csv
p, leethon, BookView, get
p, productor, CarView, post
p, car_admin, CarView, get
p, car_admin, CarView, post
p, car_admin, CarView, delete
p, car_admin, CarView, put

g, leethon, car_admin

对于以上的配置文件,我们可以进行以下的操作

import casbin
e = casbin.Enforcer("path/to/model.conf", "path/to/policy.csv")
e.enforce(请求对象,请求资源,请求方式)  # 匹配到返回True,匹配不到返回False

实际应用于django框架中,我们就用这个来编写权限类,那么我们可以从has_permission(self, request, view)方法中拿到请求对象,请求视窗资源,请求的方式,我们在执行enforce方法时,它做了如下的判断流程:

  • 读取conf中的request_definition中的字段,对enforce要接收的参数做一个定义处理,如r.sub就代表enforce接收的第一个参数

  • 读取policy_definition中的字段,对策略文件policy.csv中每一行逗号隔开的字段进行定义,除去第一列表示策略类型,后面依次对应sub,obj, act
    以上述的policy为例,sub既可以是请求用户如leethon,也可以是请求角色如car_admin。

  • 读取role_definition(这个是rbac匹配策略特有的),g _,_代表将请求用户和某类角色匹配起来

  • 读取policy_effect,这个可以认为是最终的处理策略,一般采取:如果有一个匹配项匹配到了则返回true

  • 读取matchers匹配策略,一般来说是请求r的sub,obj,act和权限策略每一行的sub,obj,act都要一一对应,有匹配项则拿出

权限类has_permission结合casbin模块编写

def has_permission(self, request, view):
    sub = request.user.username
    obj = view.__class__.__name__
    act = request.method.lower()
    e = casbin.Enforcer('app01/permission_models.conf', 'app01/permission_policy.csv')
    return e.enforce(sub, obj, act)

这样我就让权限类用简单的代码就做到了:

用户leethon可以get请求到BookView视窗
用户productor可以post请求到CarView视窗
角色car_admin可以get、post、put、delete请求到CarView视窗

用户leethon绑定了角色car_admin

这样,就得到了以下几种结果:

请求leethon BookView post会得到false
请求leethon BookView get会得到true
请求leethon CarView put会得到true
请求productor CarView get会得到false
请求productor CarView post会得到true

而这只是casbin的基础用法,这里还需要补充一些方法来让管理员或者什么接口能够编辑policy策略,让权限管理系统更好用。

posted @ 2023-02-08 19:59  leethon  阅读(212)  评论(0编辑  收藏  举报