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

Posted

技术标签:

【中文标题】为啥没有为 Postgres 视图启用行级安全性?【英文标题】:Why isn't row level security enabled for Postgres views?为什么没有为 Postgres 视图启用行级安全性? 【发布时间】:2016-02-24 18:59:21 【问题描述】:

我需要严格控制我的 Postgres 数据的读写。可更新视图始终提供对我的数据读取的非常好的、严格的控制,并允许我添加有价值的计算列。 Postgres 9.5 行级安全性引入了一种新的强大的方法来控制我的数据。但我不能同时使用这两种技术视图和行级安全性。为什么?

【问题讨论】:

如果在表上启用行级安全,然后在表上使用可更新视图,安全性不工作吗? 否,因为查询通过视图定义的角色,而不是当前角色。 那么,如何在视图定义的角色上设置行级安全性? 我有几个不同的角色访问视图,所以我丢失了这些信息。 【参考方案1】:

基本上是因为无法追溯更改视图的工作方式。我希望能够支持SECURITY INVOKER(或等效)的视图,但据我所知,目前不存在这样的功能。

您可以通过正常的行安全过滤对视图本身的访问。

视图访问的表也将应用其行安全规则。但是,他们会将current_user 视为视图创建者,因为视图以创建/拥有该视图的用户的权限访问表(和其他视图)。

如果你愿意介入并帮助开发你需要的功能,或许值得在 pgsql-hackers 上提出这个问题,或者 pgsql-general 否则?

也就是说,虽然将访问表视为创建用户并相应地更改 current_user,但它们不会阻止您在行安全策略中使用自定义 GUC、session_user 或其他上下文信息。您可以对视图使用行安全性,但不能(有用地)基于current_user 进行过滤。

【讨论】:

它将如何改变视图的工作方式? RLS 本质上不只是添加了一些WHERE 子句吗?视图不就是一个 SQL 语句吗? @Calebmer 以创建视图的用户的访问权限查看视图使用的访问表。为了允许行安全有效地过滤对通过基于访问视图的“***”用户访问的表的访问,需要更改视图访问视图中表的方式,以便不设置 current_user 等。我们有session_user,但是当你 SET SESSION AUTHORIZATION 时这不会改变,所以如果你通过 pgbouncer 或类似的方式使用池连接,它就没有用了。 哇.. 这确实需要在政策文档页面中提及。我刚刚在我们的应用程序中发现了这个问题,其中所有表都在私有模式中找到,并且它们只能通过不同模式中的视图提供给外部 API。因为这个视图是由超级用户创建的,所以 RLS 完全被破坏了,即使它已经过测试并且在真实表上运行良好。 我确实在那里发了一条消息,但它正在等待审核。 所以要解决这个问题,是否应该将视图的所有者更改为具有策略的数据库用户?【参考方案2】:

仍然可以在视图的WHERE 子句中应用行级安全策略。例如:

WHERE my_security_policy_function(person_id)

【讨论】:

以上是关于为啥没有为 Postgres 视图启用行级安全性?的主要内容,如果未能解决你的问题,请参考以下文章

Postgres 规范化表上的行级安全性

将行级安全性与列授权相结合

SQL Server 2019 中 Polybase 外部表的行级安全性可能吗?

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

行级安全(Row

BigQuery 行级安全权限