数据库角色

PostgreSQL使用角色的概念来管理数据库访问权限。角色可以被视为数据库用户或数据库用户组,具体取决于角色的设置方式。角色可以拥有数据库对象(例如,表和函数),并且可以将这些对象的权限分配给其他角色,以控制谁可以访问哪些对象。此外,可以将一个角色的成员资格授予另一个角色,从而允许成员角色使用分配给另一个角色的权限。

数据库角色在概念上与操作系统用户完全独立。实际上,保持对应关系可能很方便,但这不是必需的。数据库角色是跨数据库集群安装的全局角色(而不是每个单独的数据库)。要创建角色,请使用CREATE ROLE SQL 命令:

 

CREATE ROLE name;

name遵循 SQL 标识符的规则:要么不加特殊字符,要么用双引号引起来。(实际上,您通常希望向命令添加其他选项,例如LOGIN。更多详细信息如下。)要删除现有角色,请使用类似的DROP ROLE命令:

DROP ROLE name;

为了方便起见,提供了createuserdropuser程序作为这些 SQL 命令的包装器,可以从 shell 命令行调用这些命令:

createuser name
dropuser name

要确定现有角色集,请检查pg_roles系统目录,例如

SELECT rolname FROM pg_roles;

psql程序\du元命令对于列出现有角色也很有用。

为了引导数据库系统,新初始化的系统始终包含一个预定义角色。此角色始终是“超级用户”,默认情况下(除非在运行initdb时更改),它将具有与初始化数据库集群的操作系统用户相同的名称。通常,此角色将被命名为postgres。为了创建更多角色,您首先必须以这个初始角色的身份进行连接。

每次与数据库服务器的连接都是使用某个特定角色的名称进行的,该角色决定了在该连接中发出的命令的初始访问权限。用于特定数据库连接的角色名称由以特定于应用程序的方式发起连接请求的客户端指示。例如,psql程序使用-U命令行选项来指示要以哪个角色进行连接。许多应用程序默认采用当前操作系统用户的名称(包括createuserpsql)。因此,维护角色和操作系统用户之间的命名对应关系通常很方便。

角色属性

数据库角色可以具有许多属性,这些属性定义其权限并与客户端身份验证系统交互。

登录权限

只有具有LOGIN属性的角色才可以用作数据库连接的初始角色名称。具有LOGIN属性的角色可视为与“数据库用户”相同要创建具有登录权限的角色,请使用以下任一方法:

CREATE ROLE name LOGIN;
CREATE USER name;

CREATE USER等同于CREATE ROLE,不同之处在于CREATE USER默认假定LOGIN,而CREATE ROLE则不假定。)

超级用户状态

数据库超级用户绕过所有权限检查,但登录权限除外。这是一种危险的权限,不应随意使用;最好以非超级用户的角色完成大部分工作。要创建新的数据库超级用户,请使用CREATE ROLE name SUPERUSER。您必须以已经是超级用户的角色执行此操作。

数据库创建

必须明确授予角色创建数据库的权限(超级用户除外,因为超级用户会绕过所有权限检查)。要创建这样的角色,请使用CREATE ROLE name CREATEDB

角色创建

必须明确授予角色创建更多角色的权限(超级用户除外,因为超级用户会绕过所有权限检查)。要创建这样的角色,请使用CREATE ROLE name CREATEROLE 。具有CREATEROLE权限的角色也可以修改和删除其他角色,以及授予或撤销其中的成员资格。但是,要创建、修改、删除或更改超级用户角色的成员资格,需要超级用户身份;CREATEROLE不足以满足此要求。

 

启动复制

必须明确授予角色启动流复制的权限(超级用户除外,因为他们会绕过所有权限检查)。用于流复制的角色还必须具有LOGIN权限。要创建这样的角色,请使用CREATE ROLE name REPLICATION LOGIN

密码

仅当客户端身份验证方法要求用户在连接数据库时提供密码时,密码才有意义。密码md5身份验证方法都使用密码。数据库密码与操作系统密码是分开的。使用CREATE ROLE name PASSWORD ' string '创建角色时指定密码

提示:最好创建一个具有CREATEDBCREATEROLE权限但不是超级用户的角色,然后使用此角色进行所有数据库和角色的日常管理。这种方法可以避免以超级用户身份执行不需要的任务的危险。

角色成员资格

将用户分组通常很方便,可以简化权限管理:这样,可以向整个组授予或撤销权限。在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的权限不可用,因为即使joe间接是wheel的成员,但成员资格是通过具有NOINHERIT属性的admin获得的。之后:

SET ROLE admin;

该会话只能使用授予admin的权限,而不能使用授予joe的权限。之后:

SET ROLE wheel;

该会话只能使用授予wheel的权限,而不能使用授予joeadmin 的权限。可以使用以下任何方法恢复原始权限状态:

SET ROLE joe;
SET ROLE NONE;
RESET ROLE;

注意:SET ROLE命令始终允许选择原始登录角色直接或间接所属的任何角色。因此,在上面的例子中,在成为wheel之前无需先成为admin

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

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

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

DROP ROLE name;

删除角色

因为角色可以拥有数据库对象并拥有访问其他对象的特权,所以删除角色通常不仅仅是快速执行DROP ROLE的问题。必须先删除该角色拥有的任何对象或将其重新分配给其他所有者;并且必须撤销授予该角色的任何权限。

可以使用ALTER命令一次转移一个对象的所有权,例如:

ALTER TABLE bobs_table OWNER TO alice;

或者,可以使用REASSIGN OWNED命令将要删除的角色所拥有的所有对象的所有权重新分配给单个其他角色。由于REASSIGN OWNED无法访问其他数据库中的对象,因此需要在包含该角色所拥有的对象的每个数据库中运行它。(请注意,第一个这样的REASSIGN OWNED将更改要删除的角色所拥有的任何跨数据库共享对象(即数据库或表空间)的所有权。)

一旦任何有价值的对象被转移给新所有者,就可以使用DROP OWNED命令删除要删除的角色所拥有的任何剩余对象。同样,此命令无法访问其他数据库中的对象,因此有必要在包含角色所拥有的对象的每个数据库中运行它。此外,DROP OWNED不会删除整个数据库或表空间,因此如果角色拥有任何尚未转移给新所有者的数据库或表空间,则需要手动执行此操作。

DROP OWNED还负责删除授予目标角色的不属于该角色的对象的任何权限。由于REASSIGN OWNED不会触及此类对象,因此通常需要同时运行REASSIGN OWNEDDROP OWNED(按此顺序!)才能完全删除要删除的角色的依赖项。

简而言之,删除已用于拥有对象的角色的最通用的方法是:

REASSIGN OWNED BY doomed_role TO successor_role;
DROP OWNED BY doomed_role;
-- repeat the above commands in each database of the cluster
DROP ROLE doomed_role;

当并非所有拥有的对象都转移给同一个继任所有者时,最好手动处理异常,然后执行上述步骤进行清理。

如果在依赖对象仍然存在的情况下尝试DROP ROLE,它将发出消息标识哪些对象需要重新分配或删除。

默认角色

PostgreSQL提供了一组默认角色,这些角色提供对某些通常需要的特权功能和信息的访问权限。管理员可以将这些角色授予用户和/或他们环境中的其他角色,为这些用户提供对指定功能和信息的访问权限。

默认角色在表 21-1中描述。请注意,随着附加功能的添加,每个默认角色的具体权限将来可能会发生变化。管理员应监视发行说明以了解更改。

RoleAllowed Access
pg_signal_backend Send signals to other backends (eg: cancel query, terminate).

管理员可以使用 GRANT 命令向用户授予这些角色的访问权限:

GRANT pg_signal_backend TO admin_user;

功能安全

函数、触发器和行级安全策略允许用户将代码插入后端服务器,而其他用户可能会无意中执行这些代码。因此,这些机制允许用户相对轻松地“植入”他人的“特洛伊木马”程序。最强大的保护措施是严格控制谁可以定义对象。如果无法做到这一点,请编写仅引用具有受信任所有者的对象的查询。从search_path中删除公共架构和允许不受信任的用户创建对象的任何其他架构。

函数在后端服务器进程内运行,具有数据库服务器守护程序的操作系统权限。如果用于函数的编程语言允许未经检查的内存访问,则有可能更改服务器的内部数据结构。因此,除其他外,此类函数可以规避任何系统访问控制。允许此类访问的函数语言被视为“不受信任”PostgreSQL只允许超级用户创建用这些语言编写的函数。

 

posted @ 2024-05-27 15:11  wongchaofan  阅读(13)  评论(0编辑  收藏  举报