22.3. 角色成员资格 #
为了简化权限管理,把用户分组通常很方便:这样,权限就可以整体授予给一个组,或者从整个组中撤销。在 PostgreSQL 中,这通过创建一个表示该组的角色,然后把该组角色中的成员资格授予各个用户角色来实现。
要建立一个组角色,首先创建该角色:
CREATE ROLE name;
通常,作为组使用的角色不会有 LOGIN 属性,不过如果你愿意,也可以设置它。
一旦组角色存在,你就可以使用 GRANT 和 REVOKE 命令增加和移除成员:
GRANTgroup_roleTOrole1, ... ; REVOKEgroup_roleFROMrole1, ... ;
你也可以把成员资格授予其他组角色(因为组角色和非组角色之间其实并没有真正区别)。数据库不允许你建立循环的成员资格链。另外,不允许把某个角色中的成员资格授予 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 的权限,以及授予 admin 和 island 的任何权限,因为 joe“继承”了这些权限。然而,授予 wheel 的权限不可用,因为尽管 joe 间接是 wheel 的成员,但这层成员资格是经由使用 WITH INHERIT FALSE 授予的 admin 得来的。执行:
SET ROLE admin;
之后,会话将只能使用授予 admin 的权限,而不能使用授予 joe 或 island 的权限。再执行:
SET ROLE wheel;
之后,会话将只能使用授予 wheel 的权限,而不能使用授予 joe 或 admin 的权限。原始权限状态可通过以下任一方式恢复:
SET ROLE joe; SET ROLE NONE; RESET ROLE;
注意
SET ROLE 命令总是允许切换到原始登录角色直接或间接所属的任何角色,只要存在一条成员资格授权链,并且链上的每一段都具有 SET TRUE(默认值)。因此,在上例中,没有必要先成为 admin 再成为 wheel。另一方面,根本不可能成为 island;joe 只能通过继承来使用那些权限。
注意
在 SQL 标准中,用户与角色之间有明确区别,并且用户不会自动继承权限,而角色会。这种行为可以在 PostgreSQL 中通过让用作 SQL 角色的角色具有 INHERIT 属性,而让用作 SQL 用户的角色具有 NOINHERIT 属性来获得。不过,出于与 8.1 之前版本向后兼容的考虑,PostgreSQL 默认给所有角色都赋予 INHERIT 属性;在那些早期版本中,用户总能使用授予其所属组的权限。
角色属性 LOGIN、SUPERUSER、CREATEDB 和 CREATEROLE 可以被视为特殊权限,但它们从不会像数据库对象上的普通权限那样被继承。要使用其中之一,必须实际执行 SET ROLE 切换到拥有该属性的特定角色。继续上面的例子,我们可以选择把 CREATEDB 和 CREATEROLE 赋予 admin 角色。这样,一个以 joe 角色连接的会话并不会立即拥有这些权限,只有在执行 SET ROLE admin 之后才会拥有。
要销毁一个组角色,使用 DROP ROLE:
DROP ROLE name;
该组角色中的任何成员资格都会被自动撤销(但成员角色本身不会受到其他影响)。
报告文档问题
阅读 上游文档. 通过 PostgreSQL 文档反馈表单.