行级安全性已启用的更新不起作用,而标准更新确实使用相同的逻辑 [英] Row Level Security Enabled update is not working while standard update does using the same logic

查看:128
本文介绍了行级安全性已启用的更新不起作用,而标准更新确实使用相同的逻辑的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在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包装它-没有帮助.

我错过了什么吗?可以解决这个问题吗?

解决方案

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

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

  1. 我认为postgres允许我创建一个不带USING子句的FOR UPDATE策略,因为它允许多个相同类型的策略-但也许文档中应注意,只有一个FOR UPDATE规定必须同时包含这两个条款? 更新:我不是唯一出于相同原因而更新失败的人- PostgreSQL,无法更新行(具有行级安全性)

  2. 这使我想问The conditional expression cannot contain any aggregate or window functions限制是什么意思-如果它似乎可以使用dense_rank() over (order by...) ......凸起 解决方案

I think I found the problem - I have another FOR SELECT policy on the same table and I assumed its USING clause would be sufficient (there's an AND between policies of different FOR types) - so I did not include a USING clause in the FOR UPDATE policy. Once I added a USING (true) on the FOR UPDATE policy things started working normally (for now at least - I need to do more experiments).

Seems like it has no relation to using a window function.

  1. I assume postgres allowed me to create a FOR UPDATE policy without a USING clause since it allows multiple policies of the same type - but maybe the documentation should have a note that when having a single FOR UPDATE policy it MUST include both clauses? UPDATE: I'm not the only one who's update failed for the same reason - PostgreSQL, unable to update row ( with row level security )

  2. This leads me to ask what does the The conditional expression cannot contain any aggregate or window functions restriction mean - if it seems to work with using dense_rank() over (order by...)... raised Aggregate/Window functions restriction in Postgres Row Level Security Policy conditions

这篇关于行级安全性已启用的更新不起作用,而标准更新确实使用相同的逻辑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆