基于属性的访问控制
基于属性的访问控制根据属性/值条件授予或拒绝读取或遍历节点或关系的权限。每个基于属性的权限只能由单个属性进行限制。有关这些权限的信息和语法,请参阅读取权限。
|
使用基于属性的访问控制时,请确保用于规则的属性无法修改。可以更改此属性的用户可能会影响已授予的基于属性的权限。 |
语法
要指定权限的属性/值条件,可以使用以下语法
{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
|
用户角色无需对基于属性的权限所使用的属性拥有 |
使用另一个属性的值授予特定属性的基于属性的权限
以下示例展示了如何授予角色 regularUsers 权限,以读取 Email 或 Website 节点上域为 exampledomain.com 的 address 属性
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 等于 UNCLASSIFIED 的 OWNS 关系上的 since 属性
GRANT READ { since } ON GRAPH * FOR ()-[o:OWNS]-() WHERE o.classification = 'UNCLASSIFIED' TO regularUsers
使用 NULL 授予基于属性的权限
以下示例展示了如何授予角色 regularUsers 权限,以遍历标签为 Email 且属性 classification 为 NULL 的节点
GRANT TRAVERSE ON GRAPH * FOR (n:Email) WHERE n.classification IS NULL TO regularUsers
使用比较运算符拒绝基于属性的权限
以下示例展示了如何拒绝角色 regularUsers 权限,以读取和遍历属性 classification 与 UNCLASSIFIED 不同的节点和关系
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
|
用户角色 |
使用值列表拒绝基于属性的权限
以下示例展示了如何拒绝权限,以读取 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
|
|
|
并非所有时间值都可比较,请参阅 Cypher 手册 → 语法 → 运算符 → 值的排序和比较。 |
您可以通过运行以下命令,将上一个示例中通过命令创建的权限显示为撤销命令
SHOW ROLE regularUsers PRIVILEGES AS REVOKE COMMANDS
| 命令 |
|---|
行数: 2 |