20.4. 角色成员

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

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

CREATE ROLE name;

一般作为组使用的角色不应当具有LOGIN属性,虽然你可以设置它。

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

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

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

一个组角色的成员可以用两种方法使用组角色的权限。 首先,一个组的每个成员都可以明确用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的权限,而不包括已赋予joeadmin的权限。 原来的权限可以用下列之一恢复:

SET ROLE joe;
SET ROLE NONE;
RESET ROLE;

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

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

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

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

DROP ROLE name;

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