对象权限模型及基于django的实现
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Remove object permissions
• 删除用户或小组对某个对象的某个权限 • >>> remove_perm(‘view_task', joe, task_obj)
其它
• 添加到django的admin后台
注意
• 自定义用户模型时,需要实现自己的初始化匿名用户的方法,并在settings里将默认的初始化匿名用户 的方法名设置为自己定义的方法名
1 基于角色的访问控制(RBAC)
2 访问控制列表(ACL) 3 django-guardian 4 其它
1
基于角色的权限访问控制
• Who、What、How:who、what、how构成了访问权限三元组,也就是“Who对What进行How的操 作”。
• Who:权限的拥有者或主体 • What:权限针对的对象 • How:具体的权限(允许的操作或禁止的操作【负向授权】),包括 • 优点:用户和权限分离,通过角色对用户进行授权,简化授权过程 • 缺点:流程控制无法直接用权限模型实现
权限回收
• 使用django内置的信号
from django.contrib.contenttypes.models import ContentType from django.db.models import Q from django.db.models.signals import pre_delete from guardian.models import User from guardian.models import UserObjectPermission from guardian.models import GroupObjectPermission
>>> from guardian.shortcuts import assign_perm >>> assign_perm('view_task', joe, task) >>> joe.has_perm('view_task', task) True
Assign object permissions
权限回收
• 当删除用户和小组时,用户和小组拥有的权限也应当删除,由于django-guardian关联用户/小组和权限 时使用的是GenericForeignKey,所以在删除用户和小组时不会自动删除它们关联的对象
• 解决方法 • 执行 guardian.utils.clean_orphan_obj_perms() 方法
• RBAC3:RBAC1 + RBAC2
1 基于角色的权限访问控制(RBAC)
2 访问控制列表(ACL)
3 django-guardian 4 其它
1
访问控制列表
• 基于角色的权限访问控制,要求用户和权限分离,通过角色关联,当不同用户需要对不同资源拥有不同 操作的权限时,就会产生大量的角色
• 访问控制列表以资源为中心,将用户和权限直接关联,通过判断这个资源下某用户是否有某种权限的方 式来做权限控制
RBAC0
RBAC0
• Actor:抽象的用户概念,是直接和角色关联的主体,可以是用户或用户组 • UA:Actor和角色的关系,多对多 • PA:权限和角色的关系,多对多 • 权限:由操作和资源组合而成 • Session:主体拥有的权限的集合默认看成未激活,根据指定条件选择激活某个主体的部分或全部的权
• 优点:实现简单 • 缺点:管理复杂,由于用户直接和权限关联,增删改权限的操作会很繁琐
访问控制列表
• 权限:由操作和用户组成 • 资源和权限多对多
1 基于角色的权限访问控制(RBAC) 2 访问控制列表(ACL)
3 django-guardian
4 其它
1
django-guardian
• 基于django扩展的对象权限实现插件 • 全局权限:对某一类资源拥有的权限 • 对象权限:对单个资源具有的权限
Check object permissions
• ObjectPermissionChecker:权限检查器,缓存了用户的权限信息 • checker = ObjectPermissionChecker(joe)
装饰器
• @ p e r m is s io n _r e qu i re d _ o r_ 4 03 ( ‘ Ta s k . v ie w_ t a s k ', ( Ta s k , ‘ i d ', ‘ t a s k _ id ' ) ) • 判断登录用户是否具有指定对象的指定权限,第一个参数为权限名称,第二个参数为元组,元组中的第
>>> # Well, joe is not yet within an *employees* group >>> joe.groups.add(group) >>> joe.has_perm('change_task', task) True
wenku.baidu.com
Check object permissions
• 判断用户是否具有某种权限 • j o e . h a s _ p er m ( ‘ Ta s k . v ie w_ t a s k ' ) • 判断用户对某个对象是否具有某种权限 • joe.has_perm(‘view_task’, task_obj) • 获取用户对某个对象拥有的所有权限 • 'view_task' in get_perms(joe, task_obj) • 获取用户拥有某个权限的所有对象 • get_objects_for_user(joe, ‘task.view_task')
on_delete=models.CASCADE) created_at = models.DateTimeField(auto_now_add=True)
class Meta: permissions = ( ('view_task', 'View task'), )
Assign object permissions
限后形成一个Session
扩展的RBAC
• RBAC1:在RBAC0的基础上添加角色的继承关系,分为般继承(保证角色继承关系不会形成环)和受 限继承(每个角色可以继承于多个角色,但只能被一个角色继承,保证各个角色之间的互斥性)
• RBAC2:在RBAC0的基础上添加约束,例如某两种角色不能指派给同一用户,或者某种角色指派的用 户数量的限制,这种约束既可以作用于权限的静态分配中,也可以作用于Session中
概念变更
Django配置
• 在INSTALLED_APPS 中添加 guardian • AUTHENTICATION_BACKENDS 设置为('django.contrib.auth.backends.ModelBackend ',
'guardian.backends.ObjectPermissionBackend',)
• 添加小组对某个对象的权限
>>> from django.contrib.auth.models import User >>> boss = User.objects.create(username='Big Boss') >>> joe = User.objects.create(username='joe') >>> task = Task.objects.create(summary='Some job', content='', reported_by=boss) >>> from django.contrib.auth.models import Group >>> group = Group.objects.create(name='employees') >>> assign_perm('change_task', group, task) >>> joe.has_perm('change_task', task) False
• GUARDIAN_GET_INIT_ANONYMOUS_USER:设置初始化匿名用户使用的方法,如果自定义了 django的User,则需要设置为自己实现的方法
准备使用的模型
class Task(models.Model): summary = models.CharField(max_length=32) content = models.TextField() reported_by = models.ForeignKey(User,
4 其它
1
工作需求的初步构想
工作需求的初步构想
• 在django-guardian的基础上添加角色继承的功能 • 添加部门表,部门之间具有继承关系,每个部门对应一个角色,通过部门的继承关系和角色的继承关系
使下级部门拥有上级部门的权限 • 通过关联用户和部门使用户具有部门的权限
一个元素为对象的类型,第二个参数为字段名称,第三个参数为url参数里对应的参数名
标签
• 页面引入{% load guardian_tags %} • get_obj_perms • {% get_obj_perms user/group for obj %} • 获取用户或小组对某个对象具有哪些权限 • 返回值为权限名称组成的列表
def remove_obj_perms_connected_with_user(sender, instance, **kwargs): filters = Q(content_type=ContentType.objects.get_for_model(instance), object_pk=instance.pk) UserObjectPermission.objects.filter(filters).delete() GroupObjectPermission.objects.filter(filters).delete()
• 添加用户对某个对象的权限
>>> from django.contrib.auth.models import User >>> boss = User.objects.create(username='Big Boss') >>> joe = User.objects.create(username='joe') >>> task = Task.objects.create(summary='Some job', content='', reported_by=boss) >>> joe.has_perm('view_task', task) False
pre_delete.connect(remove_obj_perms_connected_with_user, sender=User)
官方地址
• https://django-guardian.readthedocs.io/en/stable/
1 基于角色的访问控制(RBAC) 2 访问控制列表(ACL) 43 django-guardian