5.7. 权限#
创建对象时,会为其分配一个所有者。所有者通常是执行创建语句的角色。对于大多数类型的对象,初始状态是只有所有者(或超级用户)可以对对象执行任何操作。要允许其他角色使用它,必须授予权限。
有不同类型的权限:SELECT
、INSERT
、UPDATE
、DELETE
、TRUNCATE
、REFERENCES
、TRIGGER
、CREATE
、CONNECT
、TEMPORARY
、EXECUTE
、USAGE
、SET
和ALTER SYSTEM
。适用于特定对象的权限因对象的类型(表、函数等)而异。有关这些权限含义的更多详细信息如下所示。以下部分和章节还将向您展示如何使用这些权限。
修改或销毁对象的权利是作为对象所有者的固有权利,不能被授予或撤销本身。(但是,与所有权限一样,该权利可以由所有者角色的成员继承;请参阅第 22.3 节。)
可以使用适用于该对象的适当类型的ALTER
命令将对象分配给新所有者,例如
ALTER TABLE table_name OWNER TO new_owner;
超级用户始终可以执行此操作;普通角色只能在他们既是对象的当前所有者(或继承所有者角色的权限)并且能够将SET ROLE
设置为新的所有者角色时才能执行此操作。
要分配权限,请使用GRANT命令。例如,如果joe
是一个现有角色,并且accounts
是一个现有表,则可以使用以下命令授予更新表的权限
GRANT UPDATE ON accounts TO joe;
在特定权限的位置编写ALL
将授予与对象类型相关的全部权限。
特殊的“角色”名称PUBLIC
可用于向系统上的每个角色授予权限。此外,还可以设置“组”角色,以帮助在数据库有很多用户时管理权限——有关详细信息,请参阅第 22 章。
要撤销先前授予的权限,请使用恰如其名的REVOKE命令
REVOKE ALL ON accounts FROM PUBLIC;
通常,只有对象的拥有者(或超级用户)才能授予或撤销对象上的权限。但是,可以授予具有“授予选项”的权限,这赋予接收者将其再次授予他人的权利。如果随后撤销了授予选项,那么从该接收者(直接或通过一系列授予)接收该权限的所有人将失去该权限。有关详细信息,请参阅GRANT和REVOKE参考页面。
对象的拥有者可以选择撤销自己的普通权限,例如,让自己和其他人只能读取表。但是,拥有者始终被视为持有所有授予选项,因此他们始终可以重新授予自己的权限。
可用的权限是
SELECT
#允许从表、视图、物化视图或其他类似表的对象的任何列或特定列中
SELECT
。还允许使用COPY TO
。在UPDATE
、DELETE
或MERGE
中引用现有列值时,也需要此权限。对于序列,此权限还允许使用currval
函数。对于大型对象,此权限允许读取对象。INSERT
#允许在表、视图等中
INSERT
新行。可以在特定列上授予,在这种情况下,只能在INSERT
命令中将这些列分配给(因此,其他列将接收默认值)。还允许使用COPY FROM
。UPDATE
#允许
UPDATE
表、视图等的任何列或特定列(实际上,任何非平凡的UPDATE
命令都需要SELECT
权限,因为它必须引用表列来确定要更新哪些行,和/或计算列的新值。)SELECT ... FOR UPDATE
和SELECT ... FOR SHARE
除了SELECT
权限外,还需要至少对一列具有此权限。对于序列,此权限允许使用nextval
和setval
函数。对于大型对象,此权限允许写入或截断对象。DELETE
#允许从表、视图等中
DELETE
行(实际上,任何非平凡的DELETE
命令都需要SELECT
权限,因为它必须引用表列来确定要删除哪些行)。TRUNCATE
#允许在表上
TRUNCATE
。REFERENCES
#允许创建引用表或表中特定列的外键约束。
TRIGGER
#允许在表、视图等上创建触发器。
CREATE
#对于数据库,允许在数据库中创建新架构和发布,并允许在数据库中安装受信任的扩展。
对于架构,允许在架构中创建新对象。要重命名现有对象,您必须拥有该对象和对包含架构的此权限。
对于表空间,允许在表空间中创建表、索引和临时文件,并允许创建以表空间为其默认表空间的数据库。
请注意,撤销此权限不会更改现有对象的生存或位置。
CONNECT
#允许被授予者连接到数据库。此权限在连接启动时检查(除了检查
pg_hba.conf
施加的任何限制)。TEMPORARY
#允许在使用数据库时创建临时表。
EXECUTE
#允许调用函数或过程,包括使用在函数之上实现的任何运算符。这是唯一适用于函数和过程的权限类型。
USAGE
#对于过程语言,允许使用该语言创建该语言中的函数。这是唯一适用于过程语言的权限类型。
对于架构,允许访问架构中包含的对象(假设对象的自身权限要求也得到满足)。从本质上讲,这允许被授予者在架构中“查找”对象。如果没有此权限,仍然可以通过查询系统目录等方式查看对象名称。此外,在撤销此权限后,现有会话可能具有先前执行此查找的语句,因此这不是防止对象访问的完全安全的方法。
对于序列,允许使用
currval
和nextval
函数。对于类型和域,允许在创建表、函数和其他模式对象时使用类型或域。(请注意,此权限并不能控制类型的全部“用法”,例如查询中出现的类型值。它只会阻止创建依赖于该类型的对象。此权限的主要目的是控制哪些用户可以创建对类型的依赖关系,这可能会阻止所有者稍后更改类型。)
对于外部数据封装器,允许使用外部数据封装器创建新服务器。
对于外部服务器,允许使用服务器创建外部表。被授予者还可以创建、修改或删除与其服务器关联的自己的用户映射。
SET
#允许在当前会话中将服务器配置参数设置为新值。(虽然此权限可以授予任何参数,但它只对通常需要超级用户权限才能设置的参数有意义。)
ALTER SYSTEM
#允许使用 ALTER SYSTEM 命令将服务器配置参数配置为新值。
其他命令所需的权限列在各个命令的参考页面上。
PostgreSQL 在创建对象时默认向PUBLIC
授予某些类型对象的权限。默认情况下,不会向PUBLIC
授予表、表列、序列、外部数据封装器、外部服务器、大对象、模式、表空间或配置参数的任何权限。对于其他类型的对象,授予PUBLIC
的默认权限如下:数据库的CONNECT
和TEMPORARY
(创建临时表)权限;函数和过程的EXECUTE
权限;以及语言和数据类型(包括域)的USAGE
权限。当然,对象所有者可以REVOKE
默认权限和明确授予的权限。(为了最大程度地提高安全性,请在创建对象的同一事务中发出REVOKE
;这样,其他用户就没有机会使用该对象。)此外,可以使用ALTER DEFAULT PRIVILEGES命令覆盖这些默认权限设置。
表 5.1显示了在ACL(访问控制列表)值中用于这些权限类型的单字母缩写。您将在下面列出的psql命令的输出中或查看系统目录的 ACL 列时看到这些字母。
表 5.1. ACL 权限缩写
权限 | 缩写 | 适用的对象类型 |
---|---|---|
SELECT | r (“read”) | LARGE OBJECT 、SEQUENCE 、TABLE (以及类似表的对象)、表列 |
INSERT | a (“append”) | TABLE 、表列 |
UPDATE | w (“write”) | LARGE OBJECT 、SEQUENCE 、TABLE 、表列 |
DELETE | d | TABLE |
TRUNCATE | D | TABLE |
REFERENCES | x | TABLE 、表列 |
TRIGGER | t | TABLE |
CREATE | C | DATABASE 、SCHEMA 、TABLESPACE |
CONNECT | c | DATABASE |
TEMPORARY | T | DATABASE |
EXECUTE | X | FUNCTION 、PROCEDURE |
USAGE | U | DOMAIN 、FOREIGN DATA WRAPPER 、FOREIGN SERVER 、LANGUAGE 、SCHEMA 、SEQUENCE 、TYPE |
SET | s | PARAMETER |
ALTER SYSTEM | A | PARAMETER |
表 5.2总结了每种类型的 SQL 对象可用的权限,使用上面显示的缩写。它还显示了可用于检查每种对象类型的权限设置的psql命令。
表 5.2。访问权限摘要
对象类型 | 所有权限 | 默认 PUBLIC 权限 | psql 命令 |
---|---|---|---|
DATABASE | CTc | Tc | \l |
DOMAIN | U | U | \dD+ |
FUNCTION 或 PROCEDURE | X | X | \df+ |
FOREIGN DATA WRAPPER | U | 无 | \dew+ |
FOREIGN SERVER | U | 无 | \des+ |
LANGUAGE | U | U | \dL+ |
LARGE OBJECT | rw | 无 | \dl+ |
PARAMETER | sA | 无 | \dconfig+ |
SCHEMA | UC | 无 | \dn+ |
SEQUENCE | rwU | 无 | \dp |
TABLE (以及类似表的对象) | arwdDxt | 无 | \dp |
表列 | arwx | 无 | \dp |
表空间 | C | 无 | \db+ |
类型 | U | U | \dT+ |
为特定对象授予的权限显示为aclitem
条目的列表,每个条目具有以下格式
grantee=privilege-abbreviation[*].../grantor
每个aclitem
列出由特定授权者授予的一个受让人所有的权限。特定权限由表 5.1中的一个字母缩写表示,如果使用授予选项授予权限,则附加*
。例如,calvin=r*w/hobbes
指定角色calvin
具有权限SELECT
(r
)(带授予选项 (*
))以及不可授予的权限UPDATE
(w
),两者均由角色hobbes
授予。如果calvin
还具有由不同授权者授予的同一对象上的某些权限,则这些权限将显示为单独的aclitem
条目。aclitem
中的空受让人字段表示PUBLIC
。
例如,假设用户miriam
创建表mytable
并执行
GRANT SELECT ON mytable TO PUBLIC;
GRANT SELECT, UPDATE, INSERT ON mytable TO admin;
GRANT SELECT (col1), UPDATE (col1) ON mytable TO miriam_rw;
那么psql的\dp
命令将显示
=> \dp mytable
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
--------+---------+-------+-----------------------+-----------------------+----------
public | mytable | table | miriam=arwdDxt/miriam+| col1: +|
| | | =r/miriam +| miriam_rw=rw/miriam |
| | | admin=arw/miriam | |
(1 row)
如果给定对象的“访问权限”列为空,则表示该对象具有默认权限(即其在相关系统目录中的权限条目为 null)。默认权限始终包括所有者的所有权限,并且可以包括PUBLIC
的一些权限,具体取决于对象类型,如上所述。对对象执行的第一个GRANT
或REVOKE
将实例化默认权限(例如,生成miriam=arwdDxt/miriam
),然后根据指定请求修改它们。同样,“列权限”中仅显示具有非默认权限的列的条目。(注意:出于此目的,“默认权限”始终表示对象类型的内置默认权限。其权限受ALTER DEFAULT PRIVILEGES
命令影响的对象将始终显示为包含ALTER
影响的显式权限条目。)
请注意,所有者的隐式授予选项未在访问权限显示中标记。仅当授予选项已明确授予某人时,才会出现*
。