You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL多对多关联场景下通过RLS行级安全实现租户用户过滤

解决方案

原有策略失效核心原因

  • user表本身没有tenant_id字段,无法直接做等值匹配,租户关联关系存储在user_tenant中间表中,需要通过关联查询判断权限
  • 未开启user表的行级安全总开关,即使创建了策略也不会生效
  • 示例中tenant表的id为整数类型,原有策略中强制转uuid会出现类型匹配错误

具体实现步骤

1. 开启user表的行级安全

首先执行命令开启表级RLS开关:

ALTER TABLE "user" ENABLE ROW LEVEL SECURITY;
-- 如果需要超级用户/表所有者也受RLS管控,可执行强制开启命令
ALTER TABLE "user" FORCE ROW LEVEL SECURITY;

2. 创建正确的RLS策略

通过EXISTS子句关联user_tenant中间表做权限判断,这里默认你my_user.current_tenant存储的是tenant表的id值:

CREATE POLICY tenant_policy ON "user"
USING (
  EXISTS (
    SELECT 1 FROM user_tenant
    WHERE 
      user_tenant.user_id = "user".id
      AND user_tenant.tenant_id = current_setting('my_user.current_tenant')::integer
  )
);

如果你的my_user.current_tenant存储的是租户名称(比如t1),可以调整关联逻辑连tenant表做匹配:

CREATE POLICY tenant_policy ON "user"
USING (
  EXISTS (
    SELECT 1 FROM user_tenant
    JOIN tenant ON tenant.id = user_tenant.tenant_id
    WHERE 
      user_tenant.user_id = "user".id
      AND tenant.name = current_setting('my_user.current_tenant')
  )
);

3. 验证效果

设置当前会话的租户参数后查询即可:

-- 设置当前租户为t1(对应id为1)
SET my_user.current_tenant = '1';
-- 查询user表,只会返回id为1、3的用户
SELECT * FROM "user";

注意事项

  • 测试时请使用普通权限的数据库角色,超级用户默认绕过RLS管控,除非你开启了FORCE ROW LEVEL SECURITY
  • 确保current_setting返回值和关联字段的类型完全匹配,避免类型转换错误导致策略失效

内容的提问来源于stack exchange,提问作者piyush

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 12:27:03