行级安全性已启用的更新不起作用,而标准更新确实使用相同的逻辑

时间:2019-01-10 13:54:33

标签: postgresql window-functions policy row-level-security

在postgres 10.4上工作(如果有区别,请在RDS上工作)我正在尝试使用行级安全性强制执行应用程序用户权限。

我有一个权限表,看起来像

user_group_id | entity1 | entity2 | entity3 | permission
==============|=========|=========|=========|============
1             |1        |null     |null     | write
1             |1        |1        |null     | read
  1. entity1(root)-entity2-entity3(leaf)是存储在不同表中的项目的层次结构。实体1包含实体2项,实体2包含实体3项。

  2. 权限被继承,这意味着entry3从entity2继承权限,entry2从entity1继承权限,除非:

  3. 具有匹配的entity3的行将覆盖具有匹配的entity2的行,这些行将覆盖具有匹配的entity1的行。

在上面的示例中,用户组1在实体1 = 1(第一行)下的所有实体2 /实体3上都有写入,除了实体2 = 1和实体2 = 1下的所有实体3(其已读取(第二行)等)。

我已经使用dense_rank - which is a window function作为单个查询编写了逻辑(我认为这与实际问题无关,因此不粘贴)。

当我直接将此逻辑与UPDATE一起使用时-它可以完美地工作。

当我嵌入与行级安全策略的WITH CHECK完全相同的逻辑时-update拒绝更新行(我在相关表上启用了ROW LEVEL SECURITY-就是这样)。

我试图将逻辑嵌入函数中,而不是直接嵌入策略中-但是得到了相同的结果,这意味着有效:

--not as table owner
update entity1
set col1=1
where entity1_id=10
and check_access(entity1_id); --updates 1 row

但这不是:

--as table owner
alter table entity1 enable row level security;

CREATE POLICY entity1_update
ON entity1 
AS permissive
FOR UPDATE
TO some_role
WITH CHECK ( check_access(entity1_id) );

--not as table owner
update entity1
set col1=1
where entity1_id=10; --updates no rows

阅读文档: The conditional expression cannot contain any aggregate or window functions-是这个原因吗?如果是这样,我希望在尝试创建策略或实际运行更新时会抛出错误-但什么都不会发生。

我还尝试使用带有ORDER BY的子查询重写我的访问检查逻辑,并用LIMIT包装它-没有帮助。

我想念什么吗?可以解决这个问题吗?

1 个答案:

答案 0 :(得分:0)

我认为我发现了问题-我在同一个表上还有另一个FOR SELECT策略,并且我认为它的USING子句就足够了(不同FOR类型的策略之间存在AND )-因此我没有在USING策略中包含FOR UPDATE子句。一旦我在USING (true)策略上添加了FOR UPDATE,事情就开始正常工作(至少现在-我需要做更多的实验)。

似乎与使用窗口函数无关。

  1. 我认为postgres允许我创建不带FOR UPDATE子句的USING策略,因为它允许多个相同类型的策略-但是文档中应注意在使用{strong>必须同时包含两个子句的单一FOR UPDATE政策? 更新:我不是唯一出于相同原因而更新失败的人- PostgreSQL, unable to update row ( with row level security )

  2. 这使我想问The conditional expression cannot contain any aggregate or window functions限制是什么意思-如果使用dense_rank() over (order by...) ...引发Aggregate/Window functions restriction in Postgres Row Level Security Policy conditions