一旦一个对象被创建,它会被分配一个所有者。所有者通常是执行创建语句的角色。对于大部分类型的对象,初始状态下只有所有者(或者超级用户)能够对该对象做任何事情。为了允许其他角色使用它,必须分配权限。

1 权限的类型

PostgreSQL中支持的对象级权限包括SELECT、INSERT、UPDATE、DELETE、TRUNCATE、REFERENCES、TRIGGER、CREATE、CONNECT、TEMPORARY、EXECUTE以及USAGE等以及一个附带WITH GRANT修饰符。除了GRANT外,前几类权限都可以顾名思义的猜到其含义,GRANT的在后面介绍。请注意,每种权限都有其适用的数据库资产类型,比如对于函数来说TRUNCATE权限毫无意义,对表来说EXECUTE权限也无意义。

2 入门介绍

创建数据库之前先使用管理员postgres用户创建一个角色,作为此数据库的所有者。一个特殊的名为PUBLIC的“角色”可以用来向系统中的每一个角色授予一个权限。同时,在数据库中有很多用户时可以设置“组”角色来帮助管理权限。

创建角色

create role mydb_admin login password 'postgres@123';

创建数据库并设定其所有者

create database mydb with owner = mydb_admin;

然后使用mydb_admin身份登录并创建schema和表。

3 GRANT

grant命令可以将权限授予他人。基本用法如下:

grant some_privilege to some_role;

牢记以下几条关于GRANT的使用原则。

  • 只有权限的拥有者才能将权限授予别人,并且拥有者自身还得有GRANT操作的权限。这一点是不言而喻的,因为自己没有的东西当然给不了别人。
  • 对象的所有者天然拥有此对象的所有权限,不需要再次授予。
  • 有些权限只有对象的所有者才能拥有,任何情况下都不能授予别人。这类权限包括DROP、ALTER和REVOKE,但是对象拥有者可以选择撤销他们自己的普通权限,例如把一个表变得对他们自己和其他人只读。
  • 授予时可以加上WITH GRANT OPTION子句,这意味着被授权者可以将得到的权限再次授予别人。示例如下:
#如果后来授予选项被撤销,则所有从接收人那里获得的权限(直接或者通过授权链获得)都将被撤销。
grant all on all tables in schema public to mydb_admin with grant option;
  • 如果希望一次性将某个对象的所有权限都授予某人,可以使用ALL关键字,而不需要一个个权限都写下来。
grant all on mydb_admin.my_table to mydb_admin;
  • ALL 关键字还可以用于指代某个database或者schema中的所有对象。
grant select, update on all sequences on schema my_schema to public;
  • 如果希望将权限授予所有人,可以使用PUBLIC关键字来指代所有角色。
grant usage on scheam my_schema to public;

官方手册的”GRANT“(https://www.postgresql.org/docs/current/sql-grant.html )章节中对GRANT命令的所有细节都有及其详尽的说明,建议阅读,防止设错权限导致系统安全隐患。

4 REVOKE

默认情况下,所有用户都有一组权限(SELECT, INSERT, UPDATE, DELETE, TRUNCATE,REFERENCES和TRIGGER)通过特殊角色PUBLIC连接到所有新创建的表。为了确保某个用户不再能够访问某个表,对该表的权限必须从PUBLIC和该特定用户撤销。

从用户user1撤销表table1的所有权限,运行以下SQL命令:

REVOKE ALL ON table1 FROM user1;

不过,因为所有用户通常都可以通过 PUBLIC 角色访问该表,所以还必须执行以下操作。

REVOKE ALL ON table1 FROM PUBLIC;

5 默认权限

从pg9.0开始引入了默认权限,使用默认权限,用户可以一次性针对某个特定schema或database中的所有数据库资产进行权限设置操作,哪怕这些资产还没有创建。如果你的默认全新啊更新及时,那么这样可以大大简化权限管理的工作。

假设我们希望对所有数据库用户都授予某schema中所有函数和表的EXECUTE和SELECT权限,那么我们可以按下面示例来定义权限。

定义schema的默认权限

grant usage on schema my_schema to public;

alter default privileges in schema my_schema grant select, references on tables to public;

alter default privileges in schema my_schema grant all on tables to mydb_admin with grant option;

alter default privileges in schema my_schema grant select, update on sequences to public;

alter default privileges in schema my_schema grant all on functions to mydb_admin with grant option;

alter default privileges in schema my_schema grant usage on type to public;

新增或修改默认权限并不会影响已有的权限设置,即只有当某个对象的某项权限未专门设定的情况下,默认权限设定才会生效。