2024年9月26日:PostgreSQL 17 发布!
支持的版本:当前 (17) / 16 / 15 / 14 / 13 / 12
开发版本:devel
不支持的版本:11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1

21.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,其成员资格也是通过admin,而admin是使用WITH INHERIT FALSE授予的。之后

SET ROLE admin;

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

SET ROLE wheel;

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

SET ROLE joe;
SET ROLE NONE;
RESET ROLE;

注意

SET ROLE命令始终允许选择原始登录角色直接或间接所属的任何角色,前提是存在一个成员资格授予链,其中每个成员资格都具有SET TRUE(这是默认值)。因此,在上面的示例中,不必先成为admin才能成为wheel。另一方面,完全无法成为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;

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

提交更正

如果您在文档中看到任何不正确的内容、与您对特定功能的体验不符的内容或需要进一步澄清的内容,请使用此表单报告文档问题。