Ale*_*lex 12 postgresql permissions materialized-view errors postgresql-9.3
[我认为这个问题的根本原因是我不了解权限和特权......]
所以,为了设置舞台,我的设置是一个数据库,称之为MyDb。
我有两个用户,spu1和u1,spu1是超级用户,u1是“普通”用户。MyDb的所有者是spu1。我想我还应该说u1具有从组角色继承的创建数据库和创建角色权限。
我有一个架构sch1,它是一个用户定义的架构。
在这个模式中,我有一个表,称为tbl1,还有一个物化视图,称为mvw1。
该TBL1的主人是SPU1,该mvw1的主人是U1。
在当前设置中,如上所述,我无法将mvw1刷新为u1或spu1。我只是得到以下有趣的错误(我已经广泛搜索了它,但没有找到任何可以完全解决我的设置的错误......)。
ERROR: permission denied for relation tbl1
********** Error **********
ERROR: permission denied for relation tbl1
SQL state: 42501
Run Code Online (Sandbox Code Playgroud)
我发现
我试图找出我需要授予普通用户u1缺少的权限(理想情况下所需的最低权限),以便我可以在以他们的身份登录时刷新此视图。
第一个选项虽然很高兴知道,但并不能解决我的问题。第二个选项似乎实际上是在向非超级用户授予超级用户权限,或者授予比我需要的更大的权限。
如果有人可以向我解释这里到底发生了什么(或指出我在解决问题所需的描述中遗漏了哪些信息),并让我知道我的第二个选择是否真的可行或更好的选择?
非常感谢!
Phi*_*lᵀᴹ 23
您可以使用在其所有者的安全上下文中运行的函数来执行此操作。
刷新视图的函数(使用拥有 MV/表的用户创建它):
CREATE OR REPLACE FUNCTION refresh_mvw1()
RETURNS void
SECURITY DEFINER
AS $$
BEGIN
REFRESH MATERIALIZED VIEW mvw1 with data;
RETURN;
END;
$$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)
向您希望能够刷新视图的任何用户授予对该函数的执行权限:
-- Users have 'execute' permissions by default on functions!
revoke all on function refresh_mvw1() from public;
grant execute on function refresh_mvw1() to u1;
Run Code Online (Sandbox Code Playgroud)
刷新:
select refresh_mvw1();
Run Code Online (Sandbox Code Playgroud)
来自Postgres 文档:
SECURITY DEFINER 指定函数将以创建它的用户的权限执行。
支持参数的版本:
CREATE OR REPLACE FUNCTION refresh_mv_xxx(table_name text)
RETURNS void
SECURITY DEFINER
AS $$
DECLARE sql text;
BEGIN
sql := 'REFRESH MATERIALIZED VIEW ' || table_name || ' with data';
EXECUTE sql;
RETURN;
END;
$$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)
...但我不确定动态 SQL 是否仍会作为定义者执行。
@Phil\xe1\xb5\x80\xe1\xb4\xb9\ 的第二个函数尝试容易受到 SQL 注入攻击,方法是使用:
\nSELECT refresh_mv_xxx(\'example_mview_name with data; TRUNCATE TABLE example_table_name CASCADE; REFRESH MATERIALIZED VIEW example_mview_name\')\n
Run Code Online (Sandbox Code Playgroud)\n其中example_mview_name
和example_table_name
分别指您的任何物化视图和表。
这在很多方面都是危险的。
\n我建议要么使用他的第一个尝试,要么采用以下方式:
\nCREATE OR REPLACE FUNCTION refresh_mv_dynamic(table_name text)\n RETURNS void SECURITY DEFINER\nAS $$\nDECLARE\n sql text;\nBEGIN\n sql := format(\'REFRESH MATERIALIZED VIEW %I with data\', table_name);\n EXECUTE sql;\n RETURN;\nEND;\n$$\n LANGUAGE plpgsql;\n
Run Code Online (Sandbox Code Playgroud)\n\n\n\n\n
I
将参数值视为 SQL 标识符,必要时用双引号引起来。值为空(相当于quote_ident)是错误的。
归档时间: |
|
查看次数: |
10014 次 |
最近记录: |