Skip to content

22.3. 角色成员资格#

为了方便管理权限,经常将用户分组:这样,可以向整个组授予或撤销权限。在PostgreSQL中,这是通过创建一个代表该组的角色,然后向各个用户角色授予组角色中的成员资格来完成的。

要设置组角色,首先创建角色

CREATE ROLE name;

通常,用作组的角色不会有LOGIN属性,但如果你愿意,可以设置它。

组角色存在后,你可以使用GRANTREVOKE命令添加和删除成员

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

你也可以授予其他组角色成员资格(因为组角色和非组角色之间并没有真正的区别)。数据库不会让你设置循环成员资格循环。此外,不允许授予PUBLIC角色的成员资格。

组角色的成员可以通过两种方式使用角色的权限。首先,已使用SET选项授予成员资格的成员角色可以执行SET ROLE来临时“成为”组角色。在此状态下,数据库会话可以访问组角色的权限,而不是原始登录角色的权限,并且创建的任何数据库对象都被视为由组角色而不是登录角色拥有。其次,已使用INHERIT选项授予成员资格的成员角色自动拥有那些直接或间接成为成员的角色的权限,尽管该链在缺少继承选项的成员资格处停止。例如,假设我们已经执行了

CREATE ROLE joe LOGIN;
CREATE ROLE admin;
CREATE ROLE wheel;
CREATE ROLE island;
GRANT admin TO joe WITH INHERIT TRUE;
GRANT wheel TO admin WITH INHERIT FALSE;
GRANT island TO joe WITH INHERIT TRUE, SET FALSE;

在以角色joe连接后,数据库会话将使用直接授予joe的权限以及授予adminisland的任何权限,因为joe“继承”那些权限。但是,授予wheel的权限不可用,因为即使joe间接是wheel的成员,该成员资格也是通过使用WITH INHERIT FALSE授予的admin。之后

SET ROLE admin;

会话将仅使用授予admin的那些权限,而不是授予joeisland的那些权限。之后

SET ROLE wheel;

会话将仅使用授予wheel的那些权限,而不是授予joeadmin的那些权限。可以使用以下任何命令恢复原始权限状态

SET ROLE joe;
SET ROLE NONE;
RESET ROLE;

注意

SET ROLE命令始终允许选择原始登录角色直接或间接成为其成员的任何角色,前提是存在每个都具有SET TRUE(这是默认值)的成员资格授予链。因此,在上述示例中,在成为wheel之前无需成为admin。另一方面,根本无法成为islandjoe只能通过继承访问那些权限。

注意

在 SQL 标准中,用户和角色之间存在明确的区别,用户不会自动继承权限,而角色会。在PostgreSQL中,可以通过为用作 SQL 角色的角色赋予INHERIT属性,而为用作 SQL 用户的角色赋予NOINHERIT属性来获得此行为。但是,PostgreSQL默认赋予所有角色INHERIT属性,以便向后兼容 8.1 之前的版本,在这些版本中,用户始终可以使用授予其所属组的权限。

角色属性LOGINSUPERUSERCREATEDBCREATEROLE可以被视为特殊权限,但它们永远不会像数据库对象上的普通权限那样被继承。您必须实际SET ROLE为具有这些属性之一的特定角色,才能使用该属性。继续上面的示例,我们可能会选择将CREATEDBCREATEROLE授予admin角色。然后,以角色joe连接的会话不会立即拥有这些权限,只有在执行SET ROLE admin之后才会拥有。

要销毁组角色,请使用DROP ROLE

DROP ROLE name;

组角色中的任何成员资格都会自动被撤销(但成员角色不会受到其他影响)。