Amazon dynamodb DynamoDB中用户和用户组的权限模型

Amazon dynamodb DynamoDB中用户和用户组的权限模型,amazon-dynamodb,Amazon Dynamodb,我有一个“关系”模型,具有以下类型: 使用者 用户组 项目 用户可以是多个组的一部分,并且组可以有多个用户 项具有允许读取或对其执行操作的用户和组 最常见的查询是,用户通过其id查询项目。为此,必须检查用户是否具有查询项目所需的权限。换句话说,它或它的一个组必须对该项具有权限 到目前为止我想到了什么 解决方案是,项目具有以下属性: 使用者 主键:用户id 无排序键 属性:组列表 项目: 主键:项目id 排序键: “数据”:此项目的数据 :此用户或组的权限 因此,要检查权限,必

我有一个“关系”模型,具有以下类型:

  • 使用者
  • 用户组
  • 项目
用户可以是多个组的一部分,并且组可以有多个用户

项具有允许读取或对其执行操作的用户和组

最常见的查询是,用户通过其id查询项目。为此,必须检查用户是否具有查询项目所需的权限。换句话说,它或它的一个组必须对该项具有权限

到目前为止我想到了什么

解决方案是,项目具有以下属性:

  • 使用者

    • 主键:用户id
    • 无排序键
    • 属性:组列表
  • 项目:

    • 主键:项目id
    • 排序键:
      • “数据”
        :此项目的数据
      • :此用户或组的权限
因此,要检查权限,必须

  • 获取用户的组
  • 通过以用户id和所有组id作为排序键(使用BatchGetItems)查询项目id来获取权限
  • 检查用户或其任何组是否具有所需的权限
问题

我觉得这可能会导致大量的查询,尤其是当组数很高时


有没有一种方法可以在不进行如此昂贵的权限检查的情况下实现此权限模型(或类似的权限模型)?

简短回答-将您的权限与数据分开

详细回答-您应该使用一个轻量级权限表来存储组、用户和项目之间的关系。您不应该对项目使用任何与权限相关的排序键,并且除非您有特定的原因允许使用具有相同Id的项目(例如存储项目的版本历史记录),否则您可能根本不应该对项目使用任何排序键

permissions表有两个属性,我将调用
entity
(散列键)和
relationship
(排序键)。(您可以使用您想要的任何名称。)此表还有一个GSI,其中
关系
是散列键,
实体
是排序键。因为这个表的行很小,所以查询非常便宜。您可能读取>100行,并且只消耗1个RCU

实体
属性只是一个userId或groupId。
relationship
属性是relationship类型和另一个ID的组合(您可以对ID使用任何您想要的内容,但我的所有示例都将使用数字)

以下是一些示例数据:

entity      | relationship
===========================================
user-0001   | member-of:group-1000
user-0001   | member-of:group-3000
user-0002   | can-access:item-1111
user-0002   | member-of:group-2000
group-1000  | can-access:item-1111
group-2000  | can-access:item-2222
要确定用户是否有权访问给定项目,您需要两个查询。在权限表中查询userId,并在GSI中查询“can access”itemId关系。然后,比较这两个查询结果,看看是否有共同的组(或者用户是否有直接访问该项目的权限)

例如,如果您想查看
user-0001
是否可以访问
item-1111
,您可以查询
user-0001
并返回
[成员:组-1000,成员:组-3000]
。然后,您将查询GSI的
可访问:item-1111
,然后返回
[user-0002,group-1000]
。比较这两个结果,您会发现
user-0001
可以通过
group-1000
访问
item-1111

此模型的另一个好处是,它足够灵活,可以处理其他权限用例。下面是该数据的示例:

entity      | relationship
===========================================
user-0001   | admin-of:group-1000
user-0001   | member-of:group-1000
user-0002   | member-of:group-2000
user-0002   | owner-of:item-1111
group-1000  | can-write:item-1111
group-1000  | can-read:item-1111
group-2000  | can-read:item-1111
在本例中,我们还有可以管理组的用户,我们分离了项目的读写权限,我们可以将用户或组定义为项目的所有者(这可能意味着他们可以修改具有读写项目权限的用户)


一个警告是,这假设组不能嵌套。如果可以嵌套组,则需要更多查询来遍历嵌套组的层次结构,最好使用AWS Neptune或其他数据库来存储权限