在 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 的新数据库,并让两个新用户stevemike 能够在将来执行DDL 和DML 命令 em> 表(例如,创建新表、插入数据、读取等)。这也意味着stevemike 应该能够修改和读/写彼此的表。

问题:即使我创建用户并将default privileges in schema public grant all 设置为my_db 中的表,也只有新表的创建者(steve)可以读/写表,而@ 987654330@ 不能。此外,即使postgres admin 也无法读取新表!

步骤:如何重新创建

    首先,我将创建新的数据库和用户,并授予他们更改/读取/写入my_dbfuture 表的宽松权限。
-- 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;

如果我的理解是正确的,stevemike 现在可以在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(原始表创建者)身份重新登录并授予postgresmike 权限:
-- 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;

你想要的另一件事不能以一种简单的方式得到。只有所有者(或该角色的成员)和超级用户可以ALTERDROP 一个对象。没有办法授予该特权。您唯一的解决方案是拥有一个共同的 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 所有,两个用户都可以ALTERDROP 它。

【讨论】:

有趣。我没有完全理解角色与用户的细微差别。我将创建table_owner 角色并邀请stevemike 参与其中。感谢您的回答! NOINHERIT 阻止他们创建表,除非他们运行SET ROLE

以上是关于在 Postgres 13 中未按预期工作的表设置默认权限的主要内容,如果未能解决你的问题,请参考以下文章

自动填充在 Excel 中未按预期工作

绝对底部定位在 Edge 和 IE 中未按预期工作

PYQT5 拖放行在 TableWidget 中未按预期工作

Sql 语句:在要插入的字段中未指定主键时,插入键更新未按预期工作

@State var 在 LazyVGrid 中未按预期更新

在 sql server 中未按预期实现使用 round 函数的截断