Postgresql 行级安全性的安全定义函数与视图

Postgresql 行级安全性的安全定义函数与视图,postgresql,Postgresql,我正在Postgresql 10数据库的public模式中使用。有时我会遇到这样的情况:RLS策略需要访问它创建时所在的同一个表(由于基础应用程序权限模型),或者我需要在管理上下文中查询该表以获得纯性能,因为RLS规则已经满足 为了避免无限递归(当策略中使用相同的表时)和性能原因,我创建了视图和安全定义函数 例如,表public.verbatims现在有一个由表所有者创建的视图: CREATE VIEW private.verbatims_list AS (SELECT * FROM publi

我正在Postgresql 10数据库的
public
模式中使用。有时我会遇到这样的情况:RLS策略需要访问它创建时所在的同一个表(由于基础应用程序权限模型),或者我需要在管理上下文中查询该表以获得纯性能,因为RLS规则已经满足

为了避免无限递归(当策略中使用相同的表时)和性能原因,我创建了
视图
安全定义函数

例如,表
public.verbatims
现在有一个由表所有者创建的视图:

CREATE VIEW private.verbatims_list AS (SELECT * FROM public.verbatims);
和一个函数:

CREATE OR REPLACE FUNCTION private.verbatims_list() RETURNS SETOF verbatims AS $$
  SELECT * FROM public.verbatims;
$$
STABLE
LANGUAGE SQL
SECURITY DEFINER;
两人目前都在做自己的工作

从我从Postgres关于视图(,Notes部分)和函数()的文档中收集到的信息来看,这个概念是相同的。视图/功能在拥有
所有者
权限的情况下执行。所以这对我的用例来说应该没有什么不同

然而,我想重构,这样我们就只有具有表所有者权限或安全定义函数的视图

公平地说,对于这个用例来说,两者的功能是相同的,还是我应该注意到它们之间的差异?对于用例是什么,使用函数似乎更“明确”


使用视图与函数时,更新有关可能优化的问题(来自下面的注释)

在某些情况下,函数可以“内联”:

  • 此处列出的规则被认为适用于8.4和9.5之间的pg版本。
尽管这篇文章很老,但我的测试表明安全定义函数不能“内联”(我想这是有道理的)

我创建了一个DB小提琴来演示一个简单的测试:

在简单查询中使用函数
verbatims\u list\u security()
时,Postgres使用函数扫描而不是索引扫描。我的假设是,使用索引是“内联的”

同样来自注释:当使用视图时,我的用例是否需要带有(安全屏障)()的


我目前的判断是:可能不是。因为我在HTTP api中使用RLS是为了确保多租户和acl权限,而不是为了数据仓库及其用户。我控制将哪些操作符传递给底层查询,而视图/函数从不“直接”公开。

我自己也在想这一点,尤其是wrt。优化。我担心这个函数虽然处理起来更好,但不能像内联的那样容易;然而,我不确定视图(需要使用)在这方面是否更好。@Bergi根据
SETOF
返回标记为
security definer
的函数不能正确内联。这确实有利于观点策略。我对标记为
安全屏障的视图没有任何经验,但它很重要。我也没有,这是我发现的同一页:-)我不确定信息的最新程度,或者视图内联的优化(及其问题)是否没有被记录得那么多。我自己也在想这一点,尤其是wrt。优化。我担心这个函数虽然处理起来更好,但不能像内联的那样容易;然而,我不确定视图(需要使用)在这方面是否更好。@Bergi根据
SETOF
返回标记为
security definer
的函数不能正确内联。这确实有利于观点策略。我对标记为
安全屏障的视图没有任何经验,但它很重要。我也没有,这是我发现的同一页:-)我不确定信息的最新程度,也不确定视图内联的优化(及其问题)是否没有记录得那么多。