【问题标题】:Firestore Rules multi organization multi user access rights listing dataFirestore 规则多组织多用户访问权限列表数据
【发布时间】:2019-02-27 19:05:49
【问题描述】:

我正在尝试为具有以下根集合的新 Firestore 项目设置规则集:

用户

组织

在 users 下,我们有 users/userid/ar/organisationid(ar 表示访问权限)

本文档应定义用户对给定组织的访问权限。关键是许多用户可以访问此 saas 应用程序中的一个或多个组织。

我希望再次检查该组织下的所有文档和所有子集合的访问权限。

这非常适合获取和写入,但数据列表会导致访问错误,我发现限制列表数据的唯一方法是在列出用户 ID 的文档上添加一个数组,并在此客户端上进行过滤边。这不是一个可用于生产的解决方案,因为会有很多包含许多文档的子集合。

有什么建议吗?我可以通过其他方式使列表适用于 Firestore 吗?有没有更好的方法来构建数据,或者我遗漏了什么?

我能看到的唯一其他方法是使用 firestore 函数来检查服务器端的列表,但随后我们在 @angular/fire 中丢失了很棒的东西。

过滤客户端的安全性不够。

谢谢。

目前的规则:

service cloud.firestore {
  match /databases/{database}/documents {

    match /users/{userId} {
      allow read, write: if request.auth.uid == userId;
      match /ar/{organisationDoc} {
        allow read: if request.auth.uid == userId;
        allow write: if false;
      }
    }     

    // read
    match /organisations/{oId} {
      allow get: if exists(/databases/$(database)/documents/users/$(request.auth.uid)/ar/$(oId));
      allow list: if request.auth.uid in resource.data.users;

      match /{all=**} {
        allow get: if exists(/databases/$(database)/documents/users/$(request.auth.uid)/ar/$(oId));
        allow list: if request.auth.uid in resource.data.users;
      }
    }

    // write
    match /organisations/{oId} {
      allow create: if get(/databases/$(database)/documents/users/$(request.auth.uid)/ar/$(oId)).data.create == true;
      allow update: if get(/databases/$(database)/documents/users/$(request.auth.uid)/ar/$(oId)).data.update == true;
      allow delete: if get(/databases/$(database)/documents/users/$(request.auth.uid)/ar/$(oId)).data.delete == true;

      match /{all=**} {
        allow create: if get(/databases/$(database)/documents/users/$(request.auth.uid)/ar/$(oId)).data.create == true;
        allow update: if get(/databases/$(database)/documents/users/$(request.auth.uid)/ar/$(oId)).data.update == true;
        allow delete: if get(/databases/$(database)/documents/users/$(request.auth.uid)/ar/$(oId)).data.delete == true;
      }
    }

  }
}

【问题讨论】:

    标签: firebase google-cloud-firestore firebase-security


    【解决方案1】:

    See documentation

    使用自定义声明和安全规则控制访问

    Firebase Admin SDK 支持在用户上定义自定义属性 帐户。这提供了实现各种访问的能力 Firebase 中的控制策略,包括基于角色的访问控制 应用。这些自定义属性可以为用户提供不同级别的 访问(角色),在应用程序的安全规则中强制执行。

    【讨论】:

      【解决方案2】:

      您遇到的问题是由“安全规则不是过滤器”这一事实引起的,请参阅此文档item

      换句话说,您的查询必须过滤用户具有(读取)访问权限的组织,例如,就像您对“列出usersids 的文档上的数组”所做的那样。您还可以在用户文档中将组织列表作为数组。

      使用云函数“检查服务器端的列表”并(如果我理解正确)基于此云函数调用的结果构建查询确实不理想。

      但是,当您在users/userid/ar/organisationid 下创建/修改/删除organisationid 文档时,您可以使用云函数自动填充/修改列出userids(或organizations)的数组。


      请注意,文档说:

      此行为适用于检索一个或多个文档的查询 从集合而不是单个文档检索

      正如您所提到的,这就是您的规则适用于 get() 方法的原因。

      【讨论】:

      • 是的,我明白这一点,我使它与列表一起工作的唯一方法是使用组织文档中的用户数组,并在客户端上对其进行过滤。这也不是使用云功能是理想的。您能否解释一下“您还可以将组织列表作为用户文档中的数组”来解释您的意思?因为这正是我想要做的,而用户上的“ar”集合实际上是一个组织 ID 列表。列表规则将如何查找?
      • 您可以通过在每个用户文档中列出该用户有权访问的组织作为数组来解决您的问题。然后,在您的安全规则中,您可以使用inhasAny,参见firebase.google.com/docs/firestore/solutions/role-based-accessfirebase.google.com/docs/reference/rules/rules.List#hasAny。在这种情况下,您不再需要特定的集合。
      • 基于角色的访问指南的执行方式与 i 相同,在目标文档而不是用户文档上收集,我看不到如何制定适用于列表的规则用户文档上的一个 organizationid 数组。
      • 经过进一步测试,我的原始获取规则似乎也适用于组织下的子集合,它只是不适用于组织集合本身的列表(似乎它没有 {oId}变量),据我所知,我需要组织文档上的用户数组。我想这可以通过您建议的触发功能来管理,尽管并不理想。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-21
      • 2023-02-01
      • 1970-01-01
      • 2021-06-13
      相关资源
      最近更新 更多