PostgreSQL 行级安全性涉及视图或带有连接的选择

Posted

技术标签:

【中文标题】PostgreSQL 行级安全性涉及视图或带有连接的选择【英文标题】:PostgreSQL row-level security involving a view or a select with join 【发布时间】:2017-05-12 07:26:20 【问题描述】:

(欢迎提出更好或更具描述性的标题的建议)。

我想知道在 PostgreSQL 中是否可以使用 RLS(或任何其他机制)进行以下操作。如果用户名与另一个表中的列匹配,我希望用户能够更新表的某些行。在下面的示例中,我希望在表t0 中显示为列u 的用户nene 能够更新表t2 中的列ap。我想表达的是对 t2 中的行应用策略,该策略将与以下 select 语句匹配:SELECT a, p FROM t2 INNER JOIN t1 ON (t2.t1id = t1.id) INNER JOIN t0 ON (t1.t0id = t0.id) WHERE t0.u = 'nene';

这可能吗?关于如何进行的任何建议?一个明显的解决方法是在表 t2 上复制用户名,但这会在 t2 上添加无关信息,并且需要强制执行额外的约束。

这是我的三个表(实际情况下字段更多,表 t1 不能排除在问题之外;我将其留在示例中,因为需要两个连接可能会改变解决方案空间)。

t0 是用 CREATE TABLE t0 (id TEXT PRIMARY KEY, u TEXT UNIQUE, pn TEXT); 创建的,现在包含:

=> SELECT * FROM t0;
  id  |  u  |  pn  
------+------+------
 b321 | toto | fifi
 a421 | nene | xuxu
(2 rows)

t1 是使用 CREATE TABLE t1 (id TEXT PRIMARY KEY, t0id TEXT REFERENCES t0(id), pn TEXT); 创建的,现在包含:

=> SELECT * FROM t1;
 id  | t0id |  pn  
------+------+------
x99  | a421 | lala
zy49 | a421 | popo
l2l  | b321 | nipa
(3 rows)

t2 是使用 CREATE TABLE t2 (id TEXT, t1id TEXT REFERENCES t1(id), a INET, p INT); 创建的,现在包含

=> SELECT * FROM t2;
  id  | t1id |      a      |   p   
------+------+-------------+-------
 1264 | x99  |             |      
 1267 | zy49 |             |      
 1842 | l2l  | 192.0.200.3 | 31337
 1234 | x99  | 10.0.0.89   |    23
(4 rows)

【问题讨论】:

【参考方案1】:

试试

CREATE POLICY t2_policy_update ON t2 FOR UPDATE
    USING (EXISTS (SELECT * FROM t1 INNER JOIN t0 ON (t1.t0id = t0.id) WHERE t0.u = session_user AND t1id = t1.id))

【讨论】:

谢谢。它需要在 t0 和 t1 上添加相应的权限,但这正是我需要了解它是如何工作的那种线索。

以上是关于PostgreSQL 行级安全性涉及视图或带有连接的选择的主要内容,如果未能解决你的问题,请参考以下文章

PostgreSQL 9.5 - 行级安全/ROLE 最佳实践

PostgreSQL,无法更新行(具有行级安全性)

为啥没有为 Postgres 视图启用行级安全性?

[译] PostgreSQL 行安全性策略

[译] PostgreSQL 行安全性策略

行级安全(Row