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

时间:2015-08-18 03:03:51

标签: django authorization django-rest-framework roles

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

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

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

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

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

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

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

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

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

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

2 个答案:

答案 0 :(得分:3)

听起来你想要一些字段级别的安全性。您可以考虑使用代理模型为受限用户提供对有限字段集的写访问权。

另一种选择可能是使用自定义序列化程序类,它将readonly应用于某些字段。 ViewSet子类上的get_serializer可能是进行数据透视的好地方,您应该在self.request.user中找到当前用户。

答案 1 :(得分:1)

经过深思熟虑后,我找到了两个解决方案。

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

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

此解决方案存在许多问题,并且不完全RESTful。您最终可能会得到许多不同的网址。在我的情况下,鉴于API不大且行动有限,短期内可能不是问题,但确定当应用程序的要求发生变化时,这将是一个问题。

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

我建议使用字典作为权限表的已使用数据结构,以便每个权限检查都是O(1)

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

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