问题描述
我首先尝试创建一个“租户”表,其中每一行只能由租户自己看到,然后再将类似的规则应用于引用租户主键的其他表。
我在我的策略中使用会话变量,我还想从客户端强制使用租户 UUID(不是由服务器本身生成的)。
所以一开始我创建了我的表:
CREATE TABLE tenants (
tenant_id UUID,name text UNIQUE,PRIMARY KEY("tenant_id")
)
然后我启用 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)
然后我在 tenants
表中插入 3 个条目:
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')
然后我冒充租户 1:
SET my.tenant = '9c8e4f83-c036-4fcc-a775-228887d20851'
现在我希望如果我选择所有租户,结果应该只有一行。
然而事实并非如此:
SELECT * FROM tenants
我明白了:
tenant_id | 姓名 |
---|---|
9c8e4f83-c036-4fcc-a775-228887d20851 | 租户 1 |
1953be83-683e-4960-a689-db8d53ba8cd2 | 租户 2 |
064767f7-9541-4492-9a7d-0466ac94e2ec | 租户 3 |
实际上我什至不明白在我还没有设置任何会话变量的情况下我在租户中的插入工作。感觉只是没有考虑 RLS 政策。
解决方法
行级安全有几个例外:
-
默认情况下,表所有者除外
-
任何超级用户除外
-
具有
BYPASSRLS
的任何用户都被排除在外 -
如果参数
row_security
被关闭,行级安全被禁用
从您的示例来看,您似乎属于第一类。要也为表所有者启用行级安全性,请运行
ALTER TABLE tenants FORCE ROW LEVEL SECURITY;