在 Postgres 13 中未按预期工作的表设置默认权限
Posted
技术标签:
【中文标题】在 Postgres 13 中未按预期工作的表设置默认权限【英文标题】:Setting default privileges on tables not working as expected in Postgres 13 【发布时间】:2022-01-03 00:53:56 【问题描述】:设置:我正在使用 Google Cloud Platform 的托管 Postgres 13 实例,这是一个全新安装,没有现有表或用户(除了 postgres
管理员)。
目标:我想创建一个名为my_db
的新数据库,并让两个新用户steve
和mike
能够在将来执行DDL 和DML 命令 em> 表(例如,创建新表、插入数据、读取等)。这也意味着steve
和mike
应该能够修改和读/写彼此的表。
问题:即使我创建用户并将default privileges in schema public grant all
设置为my_db
中的表,也只有新表的创建者(steve
)可以读/写表,而@ 987654330@ 不能。此外,即使postgres
admin 也无法读取新表!
步骤:如何重新创建
-
首先,我将创建新的数据库和用户,并授予他们更改/读取/写入
my_db
中future 表的宽松权限。
-- Logged in as user = postgres (Connection 1)
\c postgres
create database my_db;
-- connect to my_db and create the new users
\c my_db
-- steve user
CREATE USER steve WITH PASSWORD 'pass123';
GRANT connect ON DATABASE my_db TO steve;
alter default privileges in schema public grant all on tables to steve;
-- mike user
CREATE USER mike WITH PASSWORD 'pass456';
GRANT connect ON DATABASE my_db TO mike;
alter default privileges in schema public grant all on tables to mike;
如果我的理解是正确的,steve
和mike
现在可以在my_db
中创建和修改表。让我们测试一下。
-
然后以
steve
在新连接#2 中登录并创建新的测试表:
-- Logged in as user = steve (Connection 2)
\c my_db
create table test_tbl ( id int4 ); -- success
select * from test_tbl; -- 0 records
-
现在让我们看看
mike
是否可以从test_tbl
中读取,他应该 给予默认权限。我们为mike
创建连接#3:
-- Logged in as user = mike (Connection 3)
\c my_db
select * from test_tbl; -- ERROR: steve does not have permissions to read test_tbl!
这是我的第一个困惑点,因为我认为默认权限会让mike
读取由steve
创建的test_tbl
。
-
作为最后一个怪事,我决定回到
postgres
用户来测试阅读test_tbl
:
-- Logged in as user = postgres (Connection 1)
\c my_db
select * from test_tbl; -- ERROR: steve does not have permissions to read test_tbl!
GRANT SELECT, INSERT, UPDATE, delete ON ALL TABLES IN SCHEMA public TO mike; -- same error above!
所以即使是管理员用户postgres
也不能读取这个新表,我也不能授予权限...
-
唯一有效的方法是以
steve
(原始表创建者)身份重新登录并授予postgres
和mike
权限:
-- Logged in as user = steve (Connection 2)
\c my_db
GRANT SELECT, INSERT, UPDATE, delete ON ALL TABLES IN SCHEMA public TO postgres; -- success
GRANT SELECT, INSERT, UPDATE, delete ON ALL TABLES IN SCHEMA public TO mike; -- success
这一切似乎都倒退了。 default privileges in schema public grant all
应该注意允许用户修改未来的表,对吧?我错过了什么?
提前致谢。
【问题讨论】:
我没有看到您实际更改用户的位置。select session_user, current_user;
每一步显示什么?
同样在psql
中\dp and \ddp
为表格显示了什么?
您说您“转回 postgres 用户”,但您没有显示任何可以执行此操作的命令,并且错误消息清楚地表明您仍然是 steve,而不是 postgres。
@AdrianKlaver - 我的意思是像“--user = steve”这样的行,我使用完全不同的连接(在 DBeaver 中)切换用户。
【参考方案1】:
没有FOR ROLE
子句的ALTER DEFAULT PRIVILEGES
仅影响由运行ALTER DEFAULT PRIVILEGES
语句的角色创建的对象。
你需要两个这样的语句来得到你想要的:
ALTER DEFAULT PRIVILEGES FOR ROLE mike GRANT ... TO steve;
ALTER DEFAULT PRIVILEGES FOR ROLE steve GRANT ... TO mike;
你想要的另一件事不能以一种简单的方式得到。只有所有者(或该角色的成员)和超级用户可以ALTER
或DROP
一个对象。没有办法授予该特权。您唯一的解决方案是拥有一个共同的 table_owner
角色,并让两个用户都成为该角色的成员:
CREATE ROLE table_owner NOLOGIN;
GRANT CREATE ON SCHEMA myschema TO table_owner;
ALTER ROLE mike NOINHERIT;
ALTER ROLE steve NOINHERIT;
GRANT table_owner TO mike, steve;
现在两个用户都需要SET ROLE
在架构中创建表:
SET ROLE table_owner;
CREATE TABLE myschema.atable (...);
然后该表归table_owner
所有,两个用户都可以ALTER
或DROP
它。
【讨论】:
有趣。我没有完全理解角色与用户的细微差别。我将创建table_owner
角色并邀请steve
和mike
参与其中。感谢您的回答!
NOINHERIT
阻止他们创建表,除非他们运行SET ROLE
。以上是关于在 Postgres 13 中未按预期工作的表设置默认权限的主要内容,如果未能解决你的问题,请参考以下文章
PYQT5 拖放行在 TableWidget 中未按预期工作
Sql 语句:在要插入的字段中未指定主键时,插入键更新未按预期工作