设计基于Django Rest Framework角色的授权

new*_*log 5 django authorization roles django-rest-framework

我正在设计DRF应用程序的授权.我需要使用角色,而不仅仅是权限.

我有一个模型(例如project),其中我有一些可以由某些角色修改的信息(例如名称,描述)(例如admin).但同时还有其他角色(例如worker)不应该能够修改该模型中的信息,但仍然可以修改其他一些信息(例如,初始和最终日期).

我认为这个问题有两个解决方案.第一个是读取发送的HTTP请求,并根据请求的内容定义要采取的操作.这意味着每次将新字段添加到模型时,我都必须修改此逻辑.这听起来非常难以维护,容易出错并且可能会引入漏洞.

另一方面,我认为我可以将模型分成两个不同的模型.其中一个包含只有一个角色(admin)可以修改的数据,另一个包含可以由两个角色(admin,worker)修改的其他数据.这样,我就不必解析HTTP请求了,因为如果我得到一个影响第一个模型的POST/PUT请求而且用户有一个worker角色,我可以直接拒绝它.

这种情况发生在多个模型中.

我想知道是否有默认的方式,或者我是否正在重新发明轮子.我认为这种情况必定非常普遍.例如,我可以想到一个git项目,其中一些用户可以访问项目中的一件事而不是其他人.

补充说明(反馈将非常感谢):

  • 我很可能会使用django-role-permissions模块来实现角色和权限.我不能使用django内置组,因为虽然你可以为它们添加权限,但我会使用它们对用户进行分组(与角色没有任何关系).

  • 我将在权限文件中创建角色和权限(基于字符串的权限,例如create_project,modify_project_description)之间的关系.

  • 当收到每个请求时,我将检查哪些角色有权执行该操作,并检查用户是否是这些角色中的任何一个(基于活动的授权,这意味着在端点中我将检查活动/操作而不是角色).

new*_*log 1

经过一番思考,我找到了两个解决方案。

第一个解决方案是(而不是像我在问题中提到的那样划分模型)为必须发生的每种类型的操作声明不同的端点(URL)。然后在每个端点中serializer通过类变量定义有效参数fields

这意味着,如果一个角色只能更新某些字段,我将ModelViewSet为此操作创建一个,并且在serializer与此 ModelViewSet 相关的类中仅允许某些参数。

这个解决方案有很多问题,而且不太 RESTful。您最终可能会得到数十个不同的 URL。就我而言,鉴于 API 不大且操作有限,这在短期内可能不会成为问题,但当应用程序的需求发生变化时,肯定会成为问题。

第二个(也是选择的)解决方案是定义一个权限/角色表,在其中定义操作必须发生的端点(如果您以正确的方式构建应用程序,它可以只是类ModelViewSet名),操作执行(列出、检索、创建...)可以交互的相关模型的字段以及可以与这些字段交互的角色。

我建议使用字典作为权限表使用的数据结构,这样每次权限检查都是O(1)

现在,每次收到对该端点的请求时,都应该使用该表进行权限检查。

check_permissions()我通过重写类中的方法来实现权限检查ModelSetView。请小心并保留原始check_permissions()功能。