PostgreSQL14中预定义角色pg_write_all_data和pg_read_all_data
2022-05-09 21:32 abce 阅读(578) 评论(0) 编辑 收藏 举报场景用例:
两个数据库database1、database2;
database1有两个schema,database2有一个schema;
每个schema都属于不同的user;
database database1: schema schema1: owner: user1 table table1: columns: - id: integer - data: text table table2: columns: - id: integer - data: text schema schema2:database database1: schema schema1: owner: user1 table table1: columns: - id: integer - data: text table table2: columns: - id: integer - data: text schema schema2: owner: user2 table table1: columns: - id: integer - data: text database database2: schema schema1: owner: user1 table table1: columns: - id: integer - data: text owner: user2 table table1: columns: - id: integer - data: text database database2: schema schema1: owner: user1 table table1: columns: - id: integer - data: text
假设有个用户appuser需要访问所有的表。
在PostgreSQL13中:
首先创建user:
pg13-database1 postgres =# create user appuser; CREATE ROLE pg13-database1 postgres =# alter user appuser password 'secretsuperpasswd'; ALTER ROLE
如果我们使用新创建的用户登录,并尝试访问schema1中的表:
pg13-database1 user1 => \c database1 appuser Password for user appuser: psql (14.1, server 13.5 (Debian 13.5-1.pgdg110+1)) You are now connected to database "database1" as user "appuser". pg13-database1 user1 => select * from schema1.table1 limit 5; ERROR: permission denied for schema schema1 LINE 1: select * from schema1.table1 limit 5; ^
没有权限。那我们来给apuser授与usage权限:
Pg13-database1 postgres =# grant usage on schema schema1 to appuser; GRANT
再次尝试查看表:
pg13-database1 appuser => select * from schema1.table1 limit 5; ERROR: permission denied for table table1
再来,授予select权限:
pg13-database1 user1 => grant select on schema1.table1 to appuser; GRANT pg13-database1 appuser => select * from schema1.table1 limit 5; id | data ----+------ 1 | 1 2 | 2 3 | 3 4 | 4 5 | 5 (5 rows)
再来尝试访问相同schema中的其它表:
pg13-database1 appuser => select * from schema1.table2 limit 5; ERROR: permission denied for table table2
我们授与访问所有表的select权限:
pg13-database1 user1 => grant select on all tables in schema schema1 to appuser; GRANT pg13-database1 appuser => select * from schema1.table2 limit 5 ; id | data ----+------ 1 | 1 2 | 2 3 | 3 4 | 4 5 | 5 (5 rows)
成功了!
假如,我们发现需要新增加一个表呢?
pg13-database1 user1 => create table schema1.table3 (like schema1.table1) ; CREATE TABLE pg13-database1 user1 => insert into schema1.table3(id, data) select i,i::text from generate_series(1,1000) i; INSERT 0 1000
如果这时候使用appuser来查看表table3(之前已经授予了select所有表的权限)
pg13-database1 appuser => select * from schema1.table3 limit 5; ERROR: permission denied for table table3
还是会报没有权限。如果想查看新增加的表,还得继续按照之前的操作执行一次授权。
为了让我们的用户即使在新表也能保持读取访问权限,我们必须更改schema的默认权限:
pg13-database1 user1 => alter default privileges in schema schema1 grant select on tables to appuser; ALTER DEFAULT PRIVILEGES
现在可以查看新加的表了:
pg13-database1 user1 => create table schema1.table4 (like schema1.table1) ; CREATE TABLE pg13-database1 user1 => insert into schema1.table4(id, data) select i,i::text from generate_series(1,1000) i; INSERT 0 1000 pg13-database1 appuser => select * from schema1.table4 limit 5 ; id | data ----+------ 1 | 1 2 | 2 3 | 3 4 | 4 5 | 5 (5 rows)
但是别忘了,还有别的schema,appuser也要能访问。
pg13-database1 appuser => select * from schema2.table1 limit 5; ERROR: permission denied for schema schema2
同样,也还要按照上面的操作,再次执行一次。
别忘了,还有其它的数据库呢!
pg13-database1 appuser => \c database2 appuser psql (14.1, server 13.5 (Debian 13.5-1.pgdg110+1)) You are now connected to database "database2" as user "appuser". pg13-database2 appuser => select * from schema1.table1 limit 5; ERROR: permission denied for schema schema1
我们,还是要按照上面的操作,再次执行一次操作!!!
在postgresql14中,提供预先定义的角色:
角色 | 允许访问的范围 |
---|---|
pg_read_all_data | 读所有的数据(表、视图、序列等),即在这些对象上有select权限,在所有schemas上有usage权限;该角色不包含BYPASSRLS设置的属性; |
pg_write_all_data | 写所有的数据(表、视图、序列等),即在这些对象上有update、insert、delete权限,在所有schemas上有usage权限;该角色不包含BYPASSRLS设置的属性; |
现在,来看看在postgresql 14中是如何完成上面的场景用例的。
先创建用户
pg14-database1 postgres =# create user appuser; CREATE ROLE pg14-database1 postgres =# alter user appuser password 'supersecretpasswd'; ALTER ROLE
如果,这个时候就想访问表,肯定会报错:
pg14-database1 user1 => \c database1 appuser Password for user appuser: You are now connected to database "database1" as user "appuser". pg14-database1 appuser => select * from schema1.table1 limit 5; ERROR: permission denied for schema schema1 LINE 1: select * from schema1.table1 limit 5 ;
神奇之旅开始,我们可以使用postgresql 14中预先定义的角色:
pg14-database1 postgres =# grant pg_read_all_data to appuser ; GRANT ROLE
pg14-database1 appuser => select * from schema1.table1 limit 5 ; id | data ----+------ 1 | 1 2 | 2 3 | 3 4 | 4 5 | 5 (5 rows)
即使访问其它的schema也没有问题:
pg14-database1 appuser => select * from schema2.table1 limit 5 ; id | data ----+------ 1 | 1 2 | 2 3 | 3 4 | 4 5 | 5 (5 rows)
现在,我们新加一个表:
pg14-database1 user1 => create table schema1.table3 (like schema1.table1) ; CREATE TABLE pg14-database1 user1 => insert into schema1.table3(id, data) database1-> select i,i::text from generate_series(1,1000000) i; INSERT 0 1000000
仍然可以查询:
pg14-database1 appuser => select * from schema1.table3 limit 5; id | data ----+------ 1 | 1 2 | 2 3 | 3 4 | 4 5 | 5 (10 rows)
如果是其它数据库呢:
pg14-database1 appuser => \c database2 appuser You are now connected to database "database2" as user "appuser". pg14-database2 appuser => select * from schema1.table1 limit 5; id | data ----+------ 1 | 1 2 | 2 3 | 3 4 | 4 5 | 5 (5 rows)
还是可以访问。
pg_write_all_data的用户类似。
不过,只是直接授予DML权限,或pg_write_all_data角色,而没有read权限,用户不能对数据的子集执行update、delete操作,因为这两个操作需要过滤数据:
pg14-database1 write_appuser => \dg write_appuser List of roles Role name | Attributes | Member of ----------------+------------+--------------------- write_appuser | | {pg_write_all_data} pg14-database1 write_appuser => insert into schema1.table1(id, data) values(2000000, 'database1.schema1.table1-2000000'); INSERT 0 1 pg14-database1 write_appuser => update schema1.table1 set data = 'database1.schema1.table1-2000000-upd' where id = 2000000 ; ERROR: permission denied for table table1 pg14-database1 write_appuser => delete from schema1.table1 where id = 2000000 ; ERROR: permission denied for table table1 pg14-database1 write_appuser => update schema1.table1 set data = ''; UPDATE 1000001 pg14-database1 write_appuser => delete from schema1.table1; DELETE 1000001