18.4. 角色成员

把用户组合起来简化权限管理是个常用的便利方法:用这样的方法, 权限可以赋予整个组,也可以对整个组撤消。在 PostgreSQL 里, 这些事情是通过创建代表一个组的角色,然后赋予组角色的成员权限给独立的用户角色的方法实现的。

要设置一个组角色,首先创建角色:

CREATE ROLE name;

Typically a role being used as a group would not have the LOGIN attribute, though you can set it if you wish.

一旦组角色存在了,那么你就可以用 GRANTREVOKE 命令添加和撤消权限:

GRANT group_role TO role1, ... ;
REVOKE group_role FROM role1, ... ;

你还可以赋予成员权限给其它组角色(因为在组角色和非组角色之间没有实质的区别)。 唯一的制约是你不能建立循环的成员关系。

一个角色的成员可以用两种方法使用组角色的权限。首先,一个组的每个成员都可以明确用 SET ROLE 临时"变成"改组成员。在这个状态下,数据库会话具有该组角色的权限, 而不是原始的登录角色权限,这个时候创建的数据库对象被认为是由组角色拥有,而不是登录角色。 第二,拥有 INHERIT 属性的角色成员自动具有它们所属角色的权限。 例如,假如我们做了下面的事情:

CREATE ROLE joe LOGIN INHERIT;
CREATE ROLE admin NOINHERIT;
CREATE ROLE wheel NOINHERIT;
GRANT admin TO joe;
GRANT wheel TO admin;

那么在立即以角色 joe 连接之后,该数据库会话讲拥有直接赋予 joe 的权限加上任何赋予 admin 的权限,因为 joe "继承"admin 的权限。 不过,赋予 wheel 的权限不可用,因为即使 joewheel 的一个间接成员,但该成员关系是通过 admin 过来的, 而该组有 NOINHERIT 属性。在

SET ROLE admin;

之后,该会话将只拥有那些赋予 admin 的权限,而不包括那些赋予 joe 的权限。 在

SET ROLE wheel;

之后,该会话讲只能使用赋予 wheel 的权限,而不包括赋予 joe 或者 admine 的权限。原来的权限可以用下列之一恢复:

SET ROLE joe;
SET ROLE NONE;
RESET ROLE;

注意: SET ROLE 命令总是允许选取任意登录角色直接或者间接所在的组角色。 因此,在上面的例子里,我们没必要在变成 wheel 之前先变成 admin

注意: 在 SQL 标准里,在用户和角色之间有一个明确的区别, 并且用户并不会自动继承权限,而角色可以。这个行为在 PostgreSQL 里面可以通过给予那些当作 SQL 角色使用的角色以 INHERIT 属性, 而给予当作 SQL 用户使用的角色以 NOINHERIT 属性来实现。 不过,PostgreSQL 缺省是给予所有角色 INHERIT 属性, 目的是和 8.1 之前的版本向下兼容,那些版本里,用户总是能使用他们所在组被赋予的权限。

角色属性 LOGINSUPERUSERCREATEROLE 可以认为是特殊的权限,但是它们从来不会像数据库对象上的普通权限那样继承。 你必须真实地 SET ROLE 到一个特殊的角色,这个角色应该是拥有这些属性的角色, 然后才能利用这些属性。继续上面的例子,我们也可以选择给 admin 角色赋予 CREATEDBCREATEROLE 权限。 然后,以 joe 连接的绘画不会立即有这些权限,只有在 SET ROLE admin 之后才有。

要删除一个组角色,用 DROP ROLE

DROP ROLE name;

任何在组角色里面的成员关系都会自动撤消(但是成员角色自己则不会受影响)。 不过,请注意任何组角色拥有的对象都必须首先删除或者赋予其它所有者; 并且任何给该组角色赋予的权限都必须撤消。