Postgresql 简单行级安全性 (RLS)

Ben*_*ois 3 postgresql row-level-security

我正在努力解决基本的行级安全问题。

我首先尝试创建一个“租户”表,该表的每一行只能由租户本身看到,然后将类似的规则应用于引用租户主键的其他表。

我在策略中使用会话变量,并且还想从客户端强制执行租户 UUID(不是由服务器本身生成)。

所以首先我创建我的表:

CREATE TABLE tenants (
    tenant_id UUID,
    name text UNIQUE,
    PRIMARY KEY("tenant_id")
)
Run Code Online (Sandbox Code Playgroud)

然后我启用 RLS 和强制使用给定会话变量的策略:

ALTER TABLE tenants ENABLE ROW LEVEL SECURITY;
CREATE POLICY tenants_isolation_policy ON tenants
        USING (tenant_id = current_setting('my.tenant')::UUID)
        WITH CHECK (tenant_id = current_setting('my.tenant')::UUID)
Run Code Online (Sandbox Code Playgroud)

然后我在表中插入 3 个条目tenants

INSERT INTO "tenants" ("tenant_id", "name") VALUES ('9c8e4f83-c036-4fcc-a775-228887d20851', 'Tenant 1');
INSERT INTO "tenants" ("tenant_id", "name") VALUES ('1953be83-683e-4960-a689-db8d53ba8cd2', 'Tenant 2');
INSERT INTO "tenants" ("tenant_id", "name") VALUES ('064767f7-9541-4492-9a7d-0466ac94e2ec', 'Tenant 3')
Run Code Online (Sandbox Code Playgroud)

然后我冒充租户1:

SET my.tenant = '9c8e4f83-c036-4fcc-a775-228887d20851'
Run Code Online (Sandbox Code Playgroud)

现在我希望如果我选择所有租户,结果应该只有一行。

然而,事实并非如此:

SELECT * FROM tenants
Run Code Online (Sandbox Code Playgroud)

我得到:

租户id 姓名
9c8e4f83-c036-4fcc-a775-228887d20851 租户1
1953be83-683e-4960-a689-db8d53ba8cd2 租户2
064767f7-9541-4492-9a7d-0466ac94e2ec 租户3

我在这里缺少什么?政策怎么可能不被调用呢?

实际上,我什至不明白我在租户中的插入是否有效,而我还没有设置任何会话变量。只是感觉 RLS 政策没有被考虑在内。

Lau*_*lbe 6

行级安全性有几个例外:

  • 默认情况下,表所有者除外

  • 任何超级用户除外

  • 任何用户BYPASSRLS除外

  • row_security如果关闭该参数,则禁用行级安全性

从你的例子来看,你属于第一类。要为表所有者启用行级安全性,请运行

ALTER TABLE tenants FORCE ROW LEVEL SECURITY;
Run Code Online (Sandbox Code Playgroud)