基于属性的访问控制

基于属性的访问控制根据属性/值条件授予或拒绝读取或遍历节点或关系的权限。每个基于属性的权限只能由单个属性进行限制。有关这些权限的信息和语法,请参阅读取权限

使用基于属性的访问控制时,请确保用于规则的属性无法修改。可以更改此属性的用户可能会影响已授予的基于属性的权限。

语法

要指定权限的属性/值条件,可以使用以下语法

{GRANT | DENY | REVOKE [GRANT | DENY]}
[IMMUTABLE]
{MATCH | READ | TRAVERSE}
  ON { HOME GRAPH | GRAPH[S] { * | name[, ...] } }
    [
      ELEMENT[S] { * | label-or-rel-type[, ...] }
      | NODE[S] { * | label[, ...] }
      | RELATIONSHIP[S] { * | rel-type[, ...] }
      | FOR {
          ([var][:label["|" ...]] "{" property: value "}")
          | (var[:label["|" ...]])
            WHERE [NOT] var.property { { = | <> | > | >= | < | <= } value | IS NULL | IS NOT NULL | IN { "["[value[, ...]]"]" | listParam } }
          | (var[:label["|" ...]]
            WHERE [NOT] var.property { { = | <> | > | >= | < | <= } value | IS NULL | IS NOT NULL | IN { "["[value[, ...]]"]" | listParam } } )
          | ()[<]-"["[var][:type["|" ...]] "{" property: value "}" "]"-[>]()
          | ()[<]-"["var[:type["|" ...]]"]"-[>]()
            WHERE [NOT] var.property { { = | <> | > | >= | < | <= } value | IS NULL | IS NOT NULL | IN { "["[value[, ...]]"]" | listParam } }
          | ()[<]-"["var[:type["|" ...]]
            WHERE [NOT] var.property { { = | <> | > | >= | < | <= } value | IS NULL | IS NOT NULL | IN { "["[value[, ...]]"]" | listParam } } "]"-[>]()
      }
    ]
 {TO | FROM} role[, ...]

性能考量

在某些场景下,添加基于属性的访问控制可能会导致显著的性能开销。有关更详细的信息,请参阅限制

当存在属性规则时,以下因素可能会加剧对性能的影响

  • 相关节点和关系上的属性数量(属性越多 = 性能影响越大)。

  • 基于属性的权限数量(基于属性的权限越多 = 性能影响越大)。

  • 权限类型:TRAVERSE 基于属性的权限比 READ 基于属性的权限对性能影响更大。

  • 正在运行的存储介质类型。通过访问磁盘存储,基于属性的权限对性能的影响会显著放大。

为了减少性能影响,建议使用 block 存储格式,因为它对解析基于属性的权限所需的读取类型进行了更好的优化。

对于性能关键的场景,建议根据标签设计权限。

示例

您可以使用以下语法定义基于属性的权限

GRANT privilege-name ON GRAPH graph-name FOR pattern TO role-name

用户角色无需对基于属性的权限所使用的属性拥有 READ 权限。

使用另一个属性的值授予特定属性的基于属性的权限

以下示例展示了如何授予角色 regularUsers 权限,以读取 EmailWebsite 节点上域为 exampledomain.comaddress 属性

GRANT READ { address } ON GRAPH * FOR (n:Email|Website) WHERE n.domain = 'exampledomain.com' TO regularUsers

或者,您可以使用以下语法

GRANT READ { address } ON GRAPH * FOR (:Email|Website {domain: 'exampledomain.com'}) TO regularUsers

以下示例展示了如何授予角色 regularUsers 权限,以读取 classification 等于 UNCLASSIFIEDOWNS 关系上的 since 属性

GRANT READ { since } ON GRAPH * FOR ()-[o:OWNS]-() WHERE o.classification = 'UNCLASSIFIED' TO regularUsers

使用 NULL 授予基于属性的权限

以下示例展示了如何授予角色 regularUsers 权限,以遍历标签为 Email 且属性 classificationNULL 的节点

GRANT TRAVERSE ON GRAPH * FOR (n:Email) WHERE n.classification IS NULL TO regularUsers

使用比较运算符拒绝基于属性的权限

以下示例展示了如何拒绝角色 regularUsers 权限,以读取和遍历属性 classificationUNCLASSIFIED 不同的节点和关系

DENY MATCH {*} ON GRAPH * FOR (n) WHERE n.classification <> 'UNCLASSIFIED' TO regularUsers
DENY MATCH {*} ON GRAPH * FOR ()-[r]-() WHERE r.classification <> 'UNCLASSIFIED' TO regularUsers

使用属性值授予所有属性的基于属性的权限

以下示例展示了如何授予角色 regularUsers 权限,以读取 securityLevel 属性大于 3 的节点和关系上的所有属性

GRANT READ {*} ON GRAPH * FOR (n) WHERE n.securityLevel > 3 TO regularUsers
GRANT READ {*} ON GRAPH * FOR ()-[r]-() WHERE r.securityLevel > 3 TO regularUsers

用户角色 regularUsers 不需要对基于属性的权限所使用的 securityLevel 属性拥有 READ 权限。

使用值列表拒绝基于属性的权限

以下示例展示了如何拒绝权限,以读取 classification 属性不在 [UNCLASSIFIED, PUBLIC] 列表中的所有节点和关系上的所有属性

DENY READ {*} ON GRAPH * FOR (n) WHERE NOT n.classification IN ['UNCLASSIFIED', 'PUBLIC'] TO regularUsers
DENY READ {*} ON GRAPH * FOR ()-[r]-() WHERE NOT r.classification IN ['UNCLASSIFIED', 'PUBLIC'] TO regularUsers

使用时间值授予基于属性的权限

以下示例展示了如何授予权限,以读取 createdAt 属性晚于当前日期的节点和关系上的所有属性

GRANT READ {*} ON GRAPH * FOR (n) WHERE n.createdAt > date() TO regularUsers
GRANT READ {*} ON GRAPH * FOR ()-[r]-() WHERE r.createdAt > date() TO regularUsers

date() 函数会被求值,用于评估权限的值是基于属性的权限创建时的日期。在设计属性规则时请记住这一点,并使用 SHOW PRIVILEGES AS COMMANDS 命令检查存储的值。当撤销包含求值函数值(如 date())的基于属性的权限时,这一点至关重要。

并非所有时间值都可比较,请参阅 Cypher 手册 → 语法 → 运算符 → 值的排序和比较

您可以通过运行以下命令,将上一个示例中通过命令创建的权限显示为撤销命令

SHOW ROLE regularUsers PRIVILEGES AS REVOKE COMMANDS
表 1. 结果
命令

REVOKE GRANT READ {*} ON GRAPH * FOR (n) WHERE n.createdAt  date('2024-10-25') FROM `regularUsers`

REVOKE GRANT READ {*} ON GRAPH * FOR ()-[r]-() WHERE r.createdAt  date('2024-10-25') FROM `regularUsers`

行数: 2

© . All rights reserved.