用好PostgreSQL role membership来管理继承组权限

本文涉及的产品
云原生数据库 PolarDB 分布式版,标准版 2核8GB
云原生数据库 PolarDB MySQL 版,Serverless 5000PCU 100GB
云数据库 RDS MySQL,集群版 2核4GB 100GB
推荐场景:
搭建个人博客
简介:

用好PostgreSQL role membership来管理继承组权限

作者

digoal

日期

2016-11-14

标签

PostgreSQL , role , 角色 , membership , inherit , 权限继承


背景

在数据库中,如果你想把A用户创建的对象权限赋予给B用户,或者其他用户。

通常我们会对需要赋权的对象使用grant的语法来赋权。

但是这种方法比较繁琐,因为需要对每个对象,每一组需要的权限进行赋权。

如果你需要整个A用户所有对象的权限,以及它将来创建的对象的所有权限,有没有好的方法呢?

没错,你一定会想到role来管理。

role membership & inherit

例子

数据库有一个a 用户,创建了一些对象,需求是把a 创建的对象,自动赋予给b 用户。

创建a用户
postgres=# create role a login;
CREATE ROLE

创建b用户
postgres=# create role b login;
CREATE ROLE

把a赋予给b
postgres=# grant a to b;
GRANT ROLE

查看membership,可以看到b是a的member
postgres=# \du+ a
                  List of roles
 Role name | Attributes | Member of | Description 
-----------+------------+-----------+-------------
 a         |            | {}        | 

postgres=# \du+ b
                  List of roles
 Role name | Attributes | Member of | Description 
-----------+------------+-----------+-------------
 b         |            | {a}       | 

使用a连接数据库,创建一张表
postgres=# \c postgres a
You are now connected to database "postgres" as user "a".
postgres=> create table r1(id int);
CREATE TABLE

使用b连接数据库,可以直接使用这张表
postgres=> \c postgres b
You are now connected to database "postgres" as user "b".
postgres=> insert into r1 values (1);
INSERT 0 1
postgres=> \d+ r1
                          Table "public.r1"
 Column |  Type   | Modifiers | Storage | Stats target | Description 
--------+---------+-----------+---------+--------------+-------------
 id     | integer |           | plain   |              | 

postgres=> \dt+ r1
                    List of relations
 Schema | Name | Type  | Owner |    Size    | Description 
--------+------+-------+-------+------------+-------------
 public | r1   | table | a     | 8192 bytes | 
(1 row)

如果b用户为noinherit的,那么需要set role才能切换到对应的role.

将b设置为noinherit
postgres=> \c postgres postgres
You are now connected to database "postgres" as user "postgres".
postgres=# alter role b noinherit;
ALTER ROLE

那么b不会自动继承a这个角色,需要显示的set role a;
postgres=# \c postgres b
You are now connected to database "postgres" as user "b".
postgres=> insert into r1 values (1);
ERROR:  permission denied for relation r1

postgres=> set role a;
SET
postgres=> insert into r1 values (1);
INSERT 0 1

另一种加入member的方法是在创建角色时加入,可以一次指定多个.

postgres=# create role c  in role a login;
CREATE ROLE
postgres=# \du+ c
                  List of roles
 Role name | Attributes | Member of | Description 
-----------+------------+-----------+-------------
 c         |            | {a}       | 


d用户登陆后,会自动继承a,b的权限
postgres=# create role d  in role a,b login;
CREATE ROLE
postgres=# \du+ d
                  List of roles
 Role name | Attributes | Member of | Description 
-----------+------------+-----------+-------------
 d         |            | {a,b}     | 

WITH ADMIN OPTION

与SQL标准一样,加了WITH ADMIN OPTION 则允许被授予的用户继续将权限授予给其他人。

postgres=# grant a to b with admin option;
GRANT ROLE

postgres=# \c postgres b
You are now connected to database "postgres" as user "b".

postgres=> grant a to digoal;
GRANT ROLE

postgres=> \c postgres c
You are now connected to database "postgres" as user "c".

postgres=> grant a to digoal;
ERROR:  must have admin option on role "a"

default privilege

使用角色继承来管理有些时候还是不能满足业务需求,因为业务可能只是想把少量的权限给其他用户,而不是所有权限。

例如,使用角色继承的方法是比较危险的,被授予权限的用户,可以删除对象。

postgres=# alter role b inherit;
ALTER ROLE
postgres=# \c postgres b
You are now connected to database "postgres" as user "b".
postgres=> \dt+ r1
                    List of relations
 Schema | Name | Type  | Owner |    Size    | Description 
--------+------+-------+-------+------------+-------------
 public | r1   | table | a     | 8192 bytes | 
(1 row)

postgres=> drop table r1;
DROP TABLE

如果只想要a用户将来创建的所有表的查询权限,怎么做呢?

Command:     ALTER DEFAULT PRIVILEGES
Description: define default access privileges
Syntax:
ALTER DEFAULT PRIVILEGES
    [ FOR { ROLE | USER } target_role [, ...] ]
    [ IN SCHEMA schema_name [, ...] ]
    abbreviated_grant_or_revoke

where abbreviated_grant_or_revoke is one of:

GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }
    [, ...] | ALL [ PRIVILEGES ] }
    ON TABLES
    TO { [ GROUP ] role_name | PUBLIC } [, ...] [ WITH GRANT OPTION ]

GRANT { { USAGE | SELECT | UPDATE }
    [, ...] | ALL [ PRIVILEGES ] }
    ON SEQUENCES
    TO { [ GROUP ] role_name | PUBLIC } [, ...] [ WITH GRANT OPTION ]

GRANT { EXECUTE | ALL [ PRIVILEGES ] }
    ON FUNCTIONS
    TO { [ GROUP ] role_name | PUBLIC } [, ...] [ WITH GRANT OPTION ]

GRANT { USAGE | ALL [ PRIVILEGES ] }
    ON TYPES
    TO { [ GROUP ] role_name | PUBLIC } [, ...] [ WITH GRANT OPTION ]

REVOKE [ GRANT OPTION FOR ]
    { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }
    [, ...] | ALL [ PRIVILEGES ] }
    ON TABLES
    FROM { [ GROUP ] role_name | PUBLIC } [, ...]
    [ CASCADE | RESTRICT ]

REVOKE [ GRANT OPTION FOR ]
    { { USAGE | SELECT | UPDATE }
    [, ...] | ALL [ PRIVILEGES ] }
    ON SEQUENCES
    FROM { [ GROUP ] role_name | PUBLIC } [, ...]
    [ CASCADE | RESTRICT ]

REVOKE [ GRANT OPTION FOR ]
    { EXECUTE | ALL [ PRIVILEGES ] }
    ON FUNCTIONS
    FROM { [ GROUP ] role_name | PUBLIC } [, ...]
    [ CASCADE | RESTRICT ]

REVOKE [ GRANT OPTION FOR ]
    { USAGE | ALL [ PRIVILEGES ] }
    ON TYPES
    FROM { [ GROUP ] role_name | PUBLIC } [, ...]
    [ CASCADE | RESTRICT ]

例子

postgres=# alter default privileges for role a grant select on tables to b;
ALTER DEFAULT PRIVILEGES

postgres=# \c postgres a
You are now connected to database "postgres" as user "a".
postgres=> create table r1(id int);
CREATE TABLE
postgres=> insert into r1 values (1);
INSERT 0 1
postgres=> \c postgres b
You are now connected to database "postgres" as user "b".
postgres=> select * from r1;
 id 
----
  1
(1 row)

参考

https://www.postgresql.org/docs/9.6/static/sql-alterdefaultprivileges.html

https://www.postgresql.org/docs/9.6/static/sql-createrole.html

https://www.postgresql.org/docs/9.6/static/sql-grant.html

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
相关文章
|
2月前
|
关系型数据库 分布式数据库 数据库
【PolarDB开源】PolarDB与微服务架构的融合:灵活扩展与高效管理
【5月更文挑战第23天】阿里云PolarDB是适用于微服务的高性能分布式数据库,提供数据分片、水平扩展及高可用性解决方案。通过SQL或API实现弹性扩展,内置故障转移保障服务连续性,且兼容MySQL协议,易于集成微服务生态。通过Spring Boot示例展示了PolarDB的配置与集成过程,强调其在现代云原生应用中的重要角色。
76 1
|
2月前
|
存储 关系型数据库 Java
polardb有没有搞过pg 全量及增量备份管理的
【1月更文挑战第3天】【1月更文挑战第11篇】 polardb有没有搞过pg 全量及增量备份管理的
55 1
|
2月前
|
存储 Oracle 关系型数据库
postgresql数据库|wal日志的开启以及如何管理
postgresql数据库|wal日志的开启以及如何管理
630 0
|
8月前
|
消息中间件 存储 关系型数据库
PostgreSQL技术大讲堂 - 第33讲:并行查询管理
PostgreSQL从小白到专家,技术大讲堂 - 第33讲:并行查询管理
413 1
|
5天前
|
关系型数据库 分布式数据库 数据库
PolarDB,阿里云的开源分布式数据库,与微服务相结合,提供灵活扩展和高效管理解决方案。
【7月更文挑战第3天】PolarDB,阿里云的开源分布式数据库,与微服务相结合,提供灵活扩展和高效管理解决方案。通过数据分片和水平扩展支持微服务弹性,保证高可用性,且兼容MySQL协议,简化集成。示例展示了如何使用Spring Boot配置PolarDB,实现服务动态扩展。PolarDB缓解了微服务数据库挑战,加速了开发部署,为云原生应用奠定基础。
25 3
|
23天前
|
SQL Oracle 关系型数据库
|
3天前
|
XML 关系型数据库 MySQL
支付系统----微信支付19---集成MyBatis-plus,数据库驱动对应的依赖版本设置问题,5没版本没有cj这个依赖,mysql驱动默认的是版本8,这里是一个父类,数据库都有,写个父类,继承就行
支付系统----微信支付19---集成MyBatis-plus,数据库驱动对应的依赖版本设置问题,5没版本没有cj这个依赖,mysql驱动默认的是版本8,这里是一个父类,数据库都有,写个父类,继承就行
|
1月前
|
存储 关系型数据库 MySQL
|
11天前
|
存储 关系型数据库 数据库
经验大分享:PostgreSQL学习之【用户权限管理】说明
经验大分享:PostgreSQL学习之【用户权限管理】说明
|
2月前
|
存储 监控 安全
关系型数据库管理和维护复杂性
【5月更文挑战第3天】关系型数据库管理和维护复杂性
32 7
关系型数据库管理和维护复杂性

相关产品

  • 云原生数据库 PolarDB