我有一个PG数据库并创建了两个角色:
然后我创建用户,并为其中一个用户分配具有完全访问权限的第一个角色,为另一个用户分配只读访问权限。
接下来,我以具有完全访问权限的用户身份创建一个表,现在该表归用户所有。
然后,我尝试以只读用户身份访问表(选择)并获得拒绝权限。
我已经尝试了以下代码段:
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO READONLY_ROLE;
ALTER DEFAULT PRIVILEGES FOR ROLE FULL_ROLE IN SCHEMA public GRANT SELECT ON TABLES TO READONLY_ROLE;
我认为主要的问题是,表不是由角色拥有,而是由分配了角色的用户拥有。但是我不想将只读用户连接到完整用户。
使用这种基于角色的方法是否可行? 是否有可能将表的默认所有者以及功能表更改为完全角色而不是用户(在“创建表”之前没有“设置角色”)?
更新25.04.2019
以下是生成角色和用户的sql语句:
创建写角色:
CREATE ROLE write_role;
GRANT ALL PRIVILEGES ON DATABASE test_db TO write_role;
GRANT ALL ON SCHEMA public TO write_role;
创建阅读角色:
CREATE ROLE read_role;
GRANT CONNECT ON DATABASE test_db TO read_role;
ALTER DEFAULT PRIVILEGES GRANT SELECT ON TABLES TO read_role;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_role;
GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO read_role;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO read_role;
ALTER DEFAULT PRIVILEGES FOR ROLE write_role IN SCHEMA public GRANT SELECT ON TABLES TO read_role;
创建写用户:
CREATE USER write_user WITH ENCRYPTED PASSWORD '';
GRANT write_role TO write_user;
创建读取用户:
CREATE USER read_user WITH ENCRYPTED PASSWORD '';
GRANT read_role TO read_user;
以write_user身份创建表并插入数据:
CREATE TABLE link (
ID serial PRIMARY KEY,
url VARCHAR (255) NOT NULL,
name VARCHAR (255) NOT NULL,
description VARCHAR (255),
rel VARCHAR (50)
);
INSERT INTO link (url, name)
VALUES
('http://www.postgresqltutorial.com','PostgreSQL Tutorial');
有关表格的信息:
\dt
List of relations
Schema | Name | Type | Owner
--------+------+-------+---------------------------
public | link | table | write_user
选择为read_user:
$ select * from link;
ERROR: permission denied for table link
更新01.05.2019
多亏了一位同事在工作,我们找到了一个不是计划A而是计划Z的解决方案。本文的灵感来自:Change Ownership via Trigger
本文之所以非常重要的原因是,其他具有write_role的用户也无法删除其他用户创建的表。
这是我稍作调整的事件触发器:
CREATE OR REPLACE FUNCTION trg_create_set_owner()
RETURNS event_trigger
LANGUAGE plpgsql
AS $$
DECLARE
obj record;
BEGIN
FOR obj IN SELECT * FROM pg_event_trigger_ddl_commands() WHERE command_tag='CREATE TABLE' LOOP
EXECUTE format('ALTER TABLE %s OWNER TO write_role', obj.object_identity);
EXECUTE format('GRANT SELECT ON ALL TABLES IN SCHEMA %s to read_role', obj.schema_name);
END LOOP;
END;
$$;
CREATE EVENT TRIGGER trg_create_set_owner
ON ddl_command_end
WHEN tag IN ('CREATE TABLE')
EXECUTE PROCEDURE trg_create_set_owner();
答案 0 :(得分:0)
要检查的几件事:
编辑: 感谢您提供所有其他信息。更改默认权限仅适用于一个角色,并且不会被继承(如果用户是具有不同默认特权的多个角色的成员,我认为弄清楚对新对象应用哪些特权并不容易)。
在以写用户身份创建表之前,只需运行:
SET ROLE write_role;