由 John Doe 七月 7, 2025
你希望视图的访问权限,和底层的表访问权限一致吗?
特性提交日志
新增对 security invoker 视图的支持。
security invoker 视图在访问其底层基础关系时,会使用视图调用者的权限进行权限检查,而非视图所有者的权限。此外,如果任何基础关系是启用了行级安全策略(RLS)的表,那么将会应用视图调用者的策略,而非视图所有者的策略。
这使得视图可以在不授予底层基础关系额外权限的情况下被定义,并且与其他数据库系统中的类似功能相匹配。
它还允许视图与行级安全策略更自然地结合使用,而不会影响为用户分配的策略。
讨论:https://postgr.es/m/b66dd6d6-ad3e-c6f2-8b90-47be773da240%40cybertec.at
示例
这个特性相当不错。对于表,你可以设置权限,允许某些用户访问,而拒绝其他用户访问。
在函数方面,通常函数是以调用者的身份运行的。例如,如果执行下面的命令:
$ psql -U redrock -c "select some_function()"
那么,some_function
函数体内的所有操作(包括所有查询),都会以redrock
用户的身份执行。
但有时候,创建一个能绕过安全检查的函数是有意义的,例如,它要执行一些用户不应该“手动”执行的操作。这类函数被称为 “security definer” 函数,因为标记为该类型的函数在被调用时,会以创建该函数的用户的权限执行,而非调用者的权限。
视图在这之前一直是 “security definer” 类型的。其设计思路是,如果你创建了一个视图,就可以精细地调整对该视图的权限,而表上的权限则不那么重要。
现在,我们可以改变这种情况了。
让我们来做个测试:
$ psql -X -U redrock -c 'CREATE USER test'
$ psql -X -U redrock -c 'CREATE TABLE source_data as select id from generate_series(1,10) id'
$ psql -X -U redrock -c 'CREATE VIEW old_type_view as select * from source_data'
$ psql -X -U redrock -c 'GRANT SELECT on old_type_view to test'
$ psql -X -U redrock -c 'CREATE VIEW new_type_view with (security_invoker = true ) as select * from source_data'
$ psql -X -U redrock -c 'GRANT SELECT on new_type_view to test'
现在,以test
用户的身份操作:
$ psql -X -U test -d redrock -c "select * from old_type_view"
id
----
1
2
3
4
5
6
7
8
9
10
(10 rows)
$ psql -X -U test -d redrock -c "select * from new_type_view"
ERROR: permission denied for table source_data
旧类型的视图实际上是security_invoker = false
,即使调用者没有底层表的访问权限,也能进行查询;而新类型的视图(security_invoker = true
)则会查询失败。
非常不错的体验,感谢所有参与的社区人员。
参考
提交日志:https://git.postgresql.org/pg/commitdiff/7faa5fc84bf46ea6c543993cffb8be64dff60d25