ABAC模型简单介绍——通过casbin进行简单举例
文章目录
- ABAC模型简单介绍——通过casbin进行简单举例
- 定义
- 相关术语
- Casbin实现ABAC(Python版)
- 假设情境
- 定义对象
- 定义静态模型模板
- 测试代码
- 最终结果
- 相关链接
定义
Attribute Based Access Control (基于属性的访问控制 ),简称ABAC,通过动态计算一个或一组属性来是否满足某种条件来进行授权判断(可以编写简单的逻辑)。属性通常来说分为四类:用户属性(如用户年龄),环境属性(如当前时间),操作属性(如读取)和对象属性(如一篇文章,又称资源属性),所以理论上能够实现非常灵活的权限控制,几乎能满足所有类型的需求。
RBAC 在很多时候是管用的,比如我们的系统是面向销售公司或者学校这种组织架构很严整的地方,但是在复杂场景下,RBAC 渐渐就不够用了,它会产生很多虚无的 role 而且在管理和控制上更难:在某个医疗机构中,我们想要控制一个科室内,护士只能访问自己所负责的病人资料时,我们就无法直接使用 nurse 这个 role,我们需要更细粒度的 role 去划分病人老张还是老王,这就会产生和现实不对应的 role,例如:老张的护士,老王的护士。在医院这种病人流动性很大的场景下,频繁的创建和销毁 role 是很容易出问题,我们的确要求很频繁,但是与现实不 match 的虚无的 role 很难管理。
另一种情况是,如果管理者考虑医疗数据的安全性与隐私性,不希望护士在离开医院后能够访问到病人资料,我们会更加难办,常见的策略要么是在底层网络层进行处理,直接禁止在院外的一切访问,但是很多企业的需求往往是,使用 VPN 我依旧可以访问内部的资源,但是我还是希望基于所在地进行精确的控制,比如看邮件是可以的,但是看财务数据是不行的。在 RBAC 下,我们也可以通过虚拟的 role 来控制,比如下班后给与其 Out of Office 的 role,然后给与这个 role 最小的权限,这自然又需要虚拟的 role 与大量的动态控制。
例如规则:“允许所有班主任在上课时间自由进出校门”这条规则,其中,“班主任”是用户的角色属性,“上课时间”是环境属性,“进出”是操作属性,而“校门”就是对象属性了。为了实现便捷的规则设置和规则判断执行,ABAC通常有配置文件(XML、YAML等)或DSL配合规则解析引擎使用。
相关术语
Attribute:属性,用于表示实体特点
Subject:代指使用系统的人活着其他使用者
Object:需要管理的资源,resource
Operation:读、写、修改、拷贝等操作
Policy:通过subject、object的attribute与environment conditions一起来判断subject请求是否能够允许的关系表示(Specification Pattern)
Environment Conditions:表示目前进行访问请求发生时的操作或情境的上下文
优点:可以更细粒度的进行访问控制
缺点:定义权限时,无法直观显示用户与对象之间的关系,如果规则有点复杂或设计混乱,管理员维护和跟踪会很麻烦
大体来说就是将主体、客体的属性、情境条件以及所要进行操作组合起来,对照着策略,判断是否符合策略规则。
Casbin实现ABAC(Python版)
假设情境
主体属性需要与客体所要求的属性相同,而且所进行的操作需要被客体允许的操作包含,需要满足一定情境条件。
定义对象
# model.py
class User:def __init__(self, role, name):self.role = roleself.name = nameclass Resource:def __init__(self, name, role, action):self.name = nameself.Role = roleself.action = actionclass Env:def __init__(self, time, location):self.Time = timeself.Location = locationdef is_schooltime(self):return 8 <= self.Time.hour <= 18
定义静态模型模板
# model.conf
[request_definition]
r = sub, obj, act, env[policy_definition]
p = sub, obj, act[policy_effect]
e = some(where (p.eft == allow))[matchers] # 定义了如何匹配Policy和Request,这里指的是主体角色等级需要大于客体角色等级,已经一些其他条件
m = r.sub.Role >= r.obj.Role && r.act in r.obj.action && 8 <= r.env.Time.hour <= 18
测试代码
# test.py
from model import User, Resource, Env
from casbin import Enforcer, model
from datetime import datetimedef test() :# 创建两个用户和资源user1 = User('a', 'ck')user2 = User('b', 'zn')src1 = Resource('简历','a', ['read', 'write'])src2 = Resource('测试文件','b', ['none', 'read'])users = [user1, user2]resources = [src1, src2]# 创建一个空的模型m = model.Model()# 从本地文件中导入模型m.load_model("/home/test-casbin/test/model.conf")# 创建 Enforcer 对象时直接传入 Model 对象enforcer = Enforcer(model=m)envs = [init_env(9), init_env(23)]for env in envs :print("\n时间:", env.Time)for user in users : for resource in resources :read_allow = enforcer.enforce(user.__dict__, resource.__dict__, 'read', env.__dict__) # 传递字典write_allow = enforcer.enforce(user.__dict__, resource.__dict__, 'write', env.__dict__)print(f"{user.Role} {user.Name} 读取 {resource.name}: {read_allow}")print(f"{user.Role} {user.Name} 写 {resource.name}: {write_allow}")def init_env(hour):return Env(time=datetime(2019, 8, 20, hour, 0, 0), location="SomeLocation")if __name__ == "__main__":test()
最终结果
时间: 2019-08-20 09:00:00
a ck 读取 简历: True
a ck 写 简历: True
a ck 读取 测试文件: False
a ck 写 测试文件: False
b zn 读取 简历: True
b zn 写 简历: True
b zn 读取 测试文件: True
b zn 写 测试文件: False时间: 2019-08-20 23:00:00
a ck 读取 简历: False
a ck 写 简历: False
a ck 读取 测试文件: False
a ck 写 测试文件: False
b zn 读取 简历: False
b zn 写 简历: False
b zn 读取 测试文件: False
b zn 写 测试文件: False
相关链接
https://www.cnblogs.com/studyzy/p/11380736.html
《PML: An Interpreter-Based Access Control Policy Language for Web Services》: https://arxiv.org/pdf/1903.0975
https://github.com/casbin/pycasbin?tab=readme-ov-file