【问题标题】:Skip RLS checks temporarily暂时跳过 RLS 检查
【发布时间】:2020-02-19 19:52:48
【问题描述】:

我有已启用行级安全性和相关政策的表 - 工作得非常好。

我的问题是,有时,基于某些条件,我想在函数执行期间绕过特定语句的策略。

类似:

...
statement 1
statement 2
if (some cond) then
   disable rls temporarily 
   statement 3 -- mostly delete rows the user can't normally see
   enable rls
else
   statement 3
end if

我实现它的方式是创建一个函数check_cond,它返回一个布尔值评估some cond,并创建了一个额外的选择策略,调用这个check_cond

它有效 - 但实际问题是查询 select * from tab 现在看起来像这样: select * from tab where <original policy condition> or check_cond()

这个or check_cond() 导致postges 总是进行全表扫描,因为它无法评估预先计划的结果。

如果我能够在策略中编写“动态”代码,我将能够根据 check_cond() 的值添加/删除条件,但据我所知这是不可能的。

有什么聪明的方法可以让我在不牺牲性能的情况下暂时禁用 rls 或动态添加条件?

谢谢。

【问题讨论】:

    标签: postgresql row-level-security


    【解决方案1】:

    最简单的方法是拥有一个由超级用户拥有的 SECURITY DEFINER 函数,该函数运行:

    ALTER ROLE someuser BYPASSRLS;
    

    someuser 是运行 SQL 语句的用户。

    之后,您可以以相同的方式重新启用它。

    但这很不安全,因为没有什么能阻止用户在其他时间调用这些函数。

    更好的方法是使用BYPASSRLS 定义用户拥有的安全定义器函数,该函数会为您执行删除操作。

    注意:出于安全原因,当您定义 SECURITY DEFINER 函数时,总是 SET search_path

    【讨论】:

    • “更好的方法是使用 BYPASSRLS 定义用户拥有的安全定义器函数,该函数为您执行删除操作。” - 安全定义器是我一直在寻找的魔法词 - 这应该可以解决问题 - 谢谢!一旦我开始工作就会接受
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-21
    • 2011-03-23
    • 2019-03-17
    • 1970-01-01
    相关资源
    最近更新 更多