【问题标题】:Designing Django Rest Framework role based authorization设计基于 Django Rest Framework 角色的授权
【发布时间】:2015-11-10 19:48:48
【问题描述】:

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

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

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

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

这种情况发生在不止一个模型上。

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

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

  • 我很可能会使用django-role-permissions 模块来实现角色和权限。我不能使用 django 内置组,因为尽管您可以向它们添加权限,但我将使用它们对用户进行分组(与角色无关)。

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

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

【问题讨论】:

    标签: django authorization django-rest-framework roles


    【解决方案1】:

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

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

    【讨论】:

    • 你值得一票,因为我最终实现了你提到的所有东西(除了代理模型)。
    【解决方案2】:

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

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

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

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

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

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

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

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

    【讨论】:

      猜你喜欢
      • 2016-12-10
      • 2018-08-04
      • 2022-01-01
      • 1970-01-01
      • 2017-12-14
      • 2017-04-12
      • 2018-07-21
      • 1970-01-01
      相关资源
      最近更新 更多