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

Designing Django Rest Framework role based authorization

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

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

对于这个问题,我想到了两种解决方案。第一个是读取发送的 HTTP 请求并根据请求定义要采取的操作。这意味着每次向模型添加新字段时,我都必须修改此逻辑。这听起来很难维护,容易出错并且会引入漏洞。

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

不止一个模型会出现这种情况。

我想知道是否有默认方法,或者我是否正在重新发明轮子。我认为这种情况一定很普遍。例如,我可以想到一个 git 项目,其中一些用户有权在项目内做一件事,但其他用户则不能。

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

听起来您需要一些现场级别的安全性。您可能会考虑使用代理模型为受限用户提供对一组有限字段的写访问权。

另一种选择可能是使用自定义序列化程序 class,它只读应用于某些字段。 get_serializer 在 ViewSet subclass 上可能是进行数据透视的好地方,您应该在 self.request.user.

中找到当前用户

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

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

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

这个解决方案有很多问题,并不完全RESTful。您最终可能会得到几十个不同的 URL。在我的例子中,考虑到 API 不大并且动作有限,这在短期内可能不是问题,但当应用程序的要求发生变化时肯定会成为问题。

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

我建议使用字典作为权限 table 使用的数据结构,因此每个权限检查都是 O(1)

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

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