首页 > 解决方案 > Postgres:行级安全性不适用于视图

问题描述

当通过视图访问受行级别安全保护的表时,该表是由视图的所有者访问的,从而使 RLS 无用。

我想要的是让用户的 RLS 与用户“test_user”连接。这包括表和访问表的视图。该策略使用为事务设置的参数。我已经看到当 test_user 不是视图的所有者时,RLS 不起作用。如果我将视图的所有者更改为 test_user,它就可以工作。我想我明白,在使用视图时,表是由视图的所有者访问的,而不是访问视图的用户。

我希望用户 test_admin 成为所有表和视图的所有者。而且我想避免强制行级安全性,因为为了方便起见,我希望 test_admin 能够“绕过”RLS(在运行脚本等时)。

我试图强制行级别安全,然后添加另一个许可策略,说允许 test_admin 访问行,但这意味着 test_user 在访问视图时也会绕过 RLS。

在 Postgres 中,在使用视图时是否会绕过 RLS,因为用户将更改为视图的所有者?

--The setup. Connected as the role/user "test_admin".

    create table test_rls1
    (
    id INTEGER NOT NULL, 
    name TEXT NOT NULL,
    department_id INTEGER NOT NULL,
    PRIMARY KEY (id)
    );

    INSERT INTO test_rls1 VALUES (1, 'Peter', 1);
    INSERT INTO test_rls1 VALUES (2, 'Lisa', 2);

    CREATE POLICY test_rls1_policy ON test_rls1
     AS PERMISSIVE
     FOR SELECT
     TO PUBLIC
     USING (
             department_id = (COALESCE(nullif(current_setting('my.depid'::text, true),''),'-1'))::integer
     );

ALTER TABLE test_rls1 ENABLE ROW LEVEL SECURITY;  

CREATE VIEW test_rls1_view AS
SELECT id, name, department_id FROM test_rls1;

-- test_admin is the owner of the table and the view.
-- I have not executed "force row level security", so RLS will
-- not have effect on the test_admin user.

-- Connected as another role/user: "test_user":
-- select from the table

begin;
SELECT set_config('my.depid', '1', true);
select * from toed_rls1;
rollback;

-- This returns one row: Peter, department_id = 1

-- select from the view

    begin;
    SELECT set_config('my.depid', '1', true);
    select * from toed_rls1_view;
    rollback;

-- This returns all rows!! No RLS in effect.

标签: postgresql

解决方案


您可以选择:强制行级安全或为表和视图使用不同的所有者。


推荐阅读