PostgreSQL 是一个坚如磐石的数据库,它非常注重安全性,提供了非常丰富的基础设施来处理权限、特权和安全策略。在前面的章节中以我们介绍的基本概念为基础,重新审视角色概念,特别关注授予角色的安全性和权限(角色可以是用户,也可以是用户组)。我们将学习如何配置角色的各个方面以细致管理安全性,从连接到访问数据库中的数据。
文章目录
- 授予及回收权限
- 表相关的权限
- 基于列的权限
- 序列相关的权限
- schema 相关的权限
- schema 中的所有对象
- 编程语言相关的权限
- 例程相关的权限
- database 相关的权限
- 授予对象所有者
- 获取 ACL 信息
- 总结
授予及回收权限
在前面的小节中我们了解到,角色与权限集合相关联,这些权限通过 GRANT 语句授予,并通过 REVOKE 语句回收,权限以 ACL 的形式存储在内部。
本小节将深入探讨 GRANT 和 REVOKE 语句,以更好地帮助我们了解如何针对不同的数据库对象而它们进行不同的授权。
GRANT 语句的语法如下:
GRANT <permission, permission, ...> ON <database-object> TO <role>;
我们可以把需要的权限列出来,以逗号为分割,然后指定数据库。还可以使用 WITH GRANT OPTION 子句扩展 GRANT 语句,这将使得目标角色能够将其收到的相同权限授予另一个角色。
REVOKE 语句的语法如下:
REVOKE <permission, permission, ..> ON <database-object> FROM <role>;
在处理权限管理时,可以使用一个名为 PUBLIC 的特殊角色。它不是一个具体的角色,而是一个表示“所有可用角色”的标记。换言之,如果向 PUBLIC 授予权限,则会隐式地将此权限授予所有可用角色。
但是,“所有可用角色”是什么意思?它意味着所有现有和未来的角色。PUBLIC 角色表示在管理权限时和将来将存在于系统中的任何角色。
根据上述内容,为了防止任何用户访问我们的数据,我们应该始终从特殊的公共角色中删除所有权限,然后有选择性地授予特定角色所需的权限。也就是按需授予指定的权限。
表相关的权限
我们已经看到了与数据库表相关的主要权限。它们指的是可以针对表对象运行的主要语句,例如 SELECT、INSERT、UPDATE、DELETE 和 TRUNCATE。此外,可以使用特殊关键字 TRIGGER 和 REFERENCES 在表中创建触发器和外键。
当然,关键字 ALL 则包含了所有权限。例如,为了向 forum_stats 角色组提供读取、更新和插入数据到 categories 表中的权限,而无需授予执行其他操作的权限,我们可以在连接 forum 用户后执行以下操作:
$ psql -U forum forumdb
forumdb=> REVOKE ALL ON forum.categories FROM forum_stats;
REVOKE
forumdb=> GRANT SELECT, INSERT, UPDATE ON forum.categories TO forum_stats;
GRANT
forumdb=> \dp categories
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
--------+------------+-------+----------------------------+-------------------+----------
forum | categories | table | forum=arwdDxt/forum +| |
| | | forum_admins=arwdDxt/forum+| |
| | | taoqi=arw/forum +| |
| | | =d/forum +| |
| | | forum_stats=arw/forum | |
(1 row)
第一个 REVOKE 语句不是强制性的,但这是一个很好的做法。由于我们希望确保该角色恰好具有我们要授予的权限,而不是更多,因此先从角色中删除所有权限可以确保任何之前的 GRANT 授权语句会被回收。
基于列的权限
基于列的授权与前面的授权语法是一样的,我只需要把相关的列写出来即可。
列的授权只能应用于 SELECT、UPDATE、INSERT 和 REFERENCES 权限。
举例如下,考虑一个场景,即 forum_stats 用户组只能通过 gecos 和 username 列与 users 表交互,能够读取这两个列,但只更新第一个。权限可以由用户 forum 分配如下:
forumdb=> SELECT current_role;
current_role
--------------
forum
(1 row)
forumdb=> REVOKE ALL ON forum.users FROM forum_stats;
forumdb=> GRANT SELECT (username, gecos), UPDATE (gecos) ON forum.users TO forum_stats;
GRANT
正如我们前面建议的那样,最好先执行第一个 REVOKE 语句,以确保在我们分配我们想要的角色之前重置角色的权限。然后,我们再授予 SELECT 和 UPDATE 权限。
前面的 GRANT 语句的副作用是,forum_stats 角色不再能够执行比 GRANT 中指定的列列表更多的 SELECT 或 UPDATE。我们验证如下:
$ psql -U taoqi forumdb
-- 执行失败,不是所有的列都可以访问
forumdb=> SELECT * FROM forum.users;
ERROR: permission denied for table users
-- 执行成功
forumdb=> SELECT gecos, username FROM forum.users;
gecos | username
--------------+--------------
LAVEN LIU | laven_liu
TAO QI | taotao_qi
JAMES LEBRON | james_lebron
TAO QI 2 | taoqi
LAVEN LIU 2 | lavenliu
FORUM LI | forum
(6 rows)
-- 执行失败,username 列不允许被更新
forumdb=> UPDATE forum.users SET username = upper( username );
ERROR: permission denied for table users
-- 执行成功
forumdb=> UPDATE forum.users SET gecos = lower( gecos );
forumdb=> SELECT gecos, username FROM forum.users;
gecos | username
--------------+--------------
laven liu | laven_liu
tao qi | taotao_qi
james lebron | james_lebron
tao qi 2 | taoqi
laven liu 2 | lavenliu
forum li | forum
(6 rows)
现在让我们检查用户表的权限:
forumdb=> \dp forum.users
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
--------+-------+-------+----------------------------+------------------------+----------
forum | users | table | forum=arwdDxt/forum +| username: +|
| | | forum_admins=arwdDxt/forum | forum_stats=r/forum +|
| | | | gecos: +|
| | | | forum_stats=rw/forum+|
| | | | email: +|
| | | | forum_emails=r/forum |
(1 row)
上述输出中,用户名列具有 ACL forum_stats=r/forum
,这意味着 forum_stats 角色在此类列上具有读取权限(即 SELECT)。gecos 列具有 ACL forum_stats=rw/forum
,读作 forum_stats 角色,能够在列上读写(即 SELECT 和 UPDATE)。
我们必须要当心,不要让权限相互冲突。例如,假设我们错误地向 forum_stats 角色提供了 SELECT 权限:
forumdb=> GRANT SELECT ON forum.users TO forum_stats;
GRANT
如果我们在执行完成上述语句后检查users 表的权限,我们可以看到 ACL 已经更新如下:
forumdb=> \dp users
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
--------+-------+-------+----------------------------+------------------------+----------
forum | users | table | forum=arwdDxt/forum +| username: +|
| | | forum_admins=arwdDxt/forum+| forum_stats=r/forum +|
| | | forum_stats=r/forum | gecos: +|
| | | | forum_stats=rw/forum+|
| | | | email: +|
| | | | forum_emails=r/forum |
(1 row)
那么问题来了,在接下来执行 SELECT 语句时,哪个授权会生效呢?
这个很容易测试,PostgreSQL 认为上次授予的权限比授予列的权限更开放。因此,该角色将被赋予查看表上每列的能力:
$ psql -U taoqi forumdb
forumdb=> SELECT * FROM forum.users;
pk | username | gecos | email
----+--------------+--------------+-------------------
1 | laven_liu | laven liu | laven@google.com
2 | taotao_qi | tao qi | taoqi@lavenliu.cn
3 | james_lebron | james lebron | james@qq.com
4 | taoqi | tao qi 2 | taoqi2@apple.com
5 | lavenliu | laven liu 2 | lcc@ibm.com
6 | forum | forum li | forum@ibm.com
(6 rows)
要想解决这个问题并不像我们想象的那么简单。撤销对我们不希望角色访问的列的读取权限可能不会达到预期,即使是由表所有者(forum 用户)完成的:
$ psql -U forum forumdb
forumdb=> REVOKE SELECT (pk, email) ON users FROM forum_stats;
如果我们还记得,REVOKE 不会存储 ACL,但会修改现有的 ACL。在这种情况下,由于与前面的 pk 和 email 列没有任何关系,REVOKE语句不会改变任何内容:
forumdb=> \dp users
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
--------+-------+-------+----------------------------+------------------------+----------
forum | users | table | forum=arwdDxt/forum +| username: +|
| | | forum_admins=arwdDxt/forum+| forum_stats=r/forum +|
| | | forum_stats=r/forum | gecos: +|
| | | | forum_stats=rw/forum+|
| | | | email: +|
| | | | forum_emails=r/forum |
(1 row)
由上述输出可以看到,ACL 列表并没有发生变化。我们知道,每个特定的 GRANT 语句都可以由相应的 REVOKE 来回收。接下来我们需要执行一个不带任何列的 REVOKE 语句,如下:
$ psql -U forum forumdb
forumdb=> REVOKE SELECT ON users FROM forum_stats;
forumdb=> \dp users
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
--------+-------+-------+----------------------------+------------------------+----------
forum | users | table | forum=arwdDxt/forum +| gecos: +|
| | | forum_admins=arwdDxt/forum | forum_stats=w/forum +|
| | | | email: +|
| | | | forum_emails=r/forum |
(1 row)
执行上述 REVOKE 语句后,同事也会删除基于列的授予权限,因此在 REVOKE 之后,forum_stats 角色将不再能够对 username 和 gecos 列执行 SELECT。为了重新让该角色具有权限,我们必须为目标列重新执行 GRANT 语句。我们使用 taoqi 用户验证一下:
$ psql -U taoqi forumdb
forumdb=> SELECT username, gecos from forum.users;
ERROR: permission denied for table users
forumdb=> SELECT gecos from forum.users;
ERROR: permission denied for table users
forumdb=> SELECT email from forum.users;
email
-------------------
laven@google.com
taoqi@lavenliu.cn
james@qq.com
taoqi2@apple.com
lcc@ibm.com
forum@ibm.com
(6 rows)
序列相关的权限
序列是一个类似表的对象,它生成事务安全的新值流,通常用于自动生成(合成)键。
与序列相关的三个主要权限: USAGE 允许从序列中查询新值; SELECT 权限允许查询序列中的最后一个或当前值(但不能获取新值); 最后,UPDATE 权限是另一个特定于 PostgreSQL 的扩展,它允许设置和/或重置序列的值。
SELECT 和 UPDATE 两个权限仅允许我们对序列进行更细粒度的权限配置。
GRANT 和 REVOKE 语句的一般语法如下:
GRANT <permission> ON SEQUENCE <sequence> TO <role>;
REVOKE <permission> ON SEQUENCE <sequence> FROM <role>;
特殊关键字 ALL 则包含了适用于序列的所有权限。
为了理解序列的权限如何工作,让我们考虑用于生成 categories 表主键的序列:categories_pk_seq。
首先,回收 taoqi 角色的所有序列的权限,以便它无法再与序列交互:
$ psql -U forum forumdb
forumdb=> REVOKE ALL ON SEQUENCE categories_pk_seq FROM taoqi;
REVOKE
现在,如果 taoqi 角色试图从序列中获取新值,它会收到一个权限被拒绝的错误:
$ psql -U taoqi forumdb
forumdb=> SELECT nextval( 'forum.categories_pk_seq' );
ERROR: permission denied for sequence categories_pk_seq
再次授予允许 taoqi 角色再次查询序列:
$ psql -U forum forumdb
forumdb=> GRANT USAGE ON SEQUENCE categories_pk_seq TO taoqi;
GRANT
现在,taoqi 角色可以成功执行 nextval 函数:
$ psql -U taoqi forumdb
forumdb=> \dp forum.categories_pk_seq
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
--------+-------------------+----------+-------------------+-------------------+----------
forum | categories_pk_seq | sequence | forum=rwU/forum +| |
| | | taoqi=U/forum | | -- 这里的 U 表示 Usage,Usage 包含了 SELECT 权限
(1 row)
forumdb=> SELECT nextval( 'forum.categories_pk_seq' );
nextval
---------
11
(1 row)
-- setval 函数是否可以执行呢?
forumdb=> SELECT setval( 'forum.categories_pk_seq', 10 );
ERROR: permission denied for sequence categories_pk_seq
但是 taoqi 角色并不能执行 setval 函数,接下来我们授予 taoq 对 categories_pk_seq 序列的更新权限:
$ psql -U forum forumdb
forumdb=> GRANT USAGE, UPDATE ON SEQUENCE forum.categories_pk_seq TO taoqi;
GRANT
-- 验证一下 ACL
forumdb=> \dp categories_pk_seq
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
--------+-------------------+----------+-------------------+-------------------+----------
forum | categories_pk_seq | sequence | forum=rwU/forum +| |
| | | taoqi=wU/forum | |
(1 row)
切换到 taoqi 用户再次执行 setval 函数:
$ psql -U taoqi forumdb
forumdb=> SELECT setval( 'forum.categories_pk_seq', 10 );
setval
--------
10
(1 row)
forumdb=> SELECT nextval( 'forum.categories_pk_seq' );
nextval
---------
11
(1 row)
schema 相关的权限
由前面的章节中介绍的,schema 是各种对象的命名空间,主要包含表和视图,但也包括函数、例程和其他数据库对象。主要有两种权限可以应用于模式:CREATE,允许在模式中创建对象,USAGE,允许角色在模式中使用对象。
令人有些困惑的是,如果角色没有 USAGE 权限,即使它是所有者,它也无法访问对象。
对 schema 进行授权与回收权限的语法如下:
-- 授予权限
GRANT <permission> ON SCHEMA <schema> TO <role>;
-- 回收权限
REVOKE <permission> ON SCHEMA <schema> FROM <role>;
关键字 ALL 则包含了所有的权限。为了更好地了解两种不同的权限,让我们创建一个名为 configuration 的 schema,看看如何启用对它的访问:
$ psql -U forum forumdb
forumdb=> CREATE SCHEMA configuration;
CREATE SCHEMA
该模式是由 forum 用户创建的,因此用户 taoqi 没有任何权限,因此它无法在该 schema 下创建表:
$ psql -U taoqi forumdb
forumdb=> CREATE TABLE configuration.conf( param text,
value text,
UNIQUE (param) );
ERROR: permission denied for schema configuration
为了允许用户 taoqi 在模式中创建新对象,必须授予 CREATE 权限。接下来我们需要同时提供 CREATE 及 USAGE 权限:
$ psql -U forum forumdb
forumdb=> GRANT CREATE ON SCHEMA configuration TO taoqi;
GRANT
forumdb=> GRANT USAGE ON SCHEMA configuration TO taoqi;
GRANT
经过上面的授权后,taoqi 角色现在可以在模式中创建一个新对象:
$ psql -U taoqi forumdb
forumdb=> CREATE TABLE configuration.conf( param text,
value text,
UNIQUE (param) );
CREATE TABLE
forumdb=> INSERT INTO configuration.conf
VALUES( 'posts_per_page', '10' );
INSERT 0 1
如果没有 USAGE 权限,角色将无法再访问模式中的任何对象,即使它是对象的所有者:
$ psql -U forum forumdb
forumdb=> REVOKE USAGE ON SCHEMA configuration FROM taoqi;
REVOKE
经过权限回收后,用户 taoqi 无法再读取自己的数据:
$ psql -U taoqi forumdb
forumdb=> SELECT * FROM configuration.conf;
ERROR: permission denied for schema configuration
通常我们允许角色操纵特定模式中包含的一些数据,但同时不授予其创建新数据库对象(如表)的能力。例如:
$ psql -U forum forumdb
forumdb=> GRANT USAGE ON SCHEMA configuration TO taoqi;
GRANT
forumdb=> REVOKE CREATE ON SCHEMA configuration FROM taoqi;
REVOKE
我们可以将模式视为其他对象的容器。要访问容器,我们必须具有 USAGE 权限,要创建新对象,我们必须具有 CREATE 权限。
schema 中的所有对象
如何授予 schema 中所有对象的权限呢?可以使用 ALL <objects> IN SCHEMA
子句。操作如下:
$ psql -U postgres forumdb
forumdb=# REVOKE ALL
ON ALL TABLES IN SCHEMA configuration
FROM taoqi;
REVOKE
forumdb=# GRANT SELECT, INSERT, UPDATE
ON ALL TABLES IN SCHEMA configuration
TO taoqi;
GRANT
-- 查看一下权限
forumdb=> \dp configuration.conf
Access privileges
Schema │ Name │ Type │ Access privileges │ Column privileges │ Policies
═══════════════╪══════╪═══════╪═══════════════════╪═══════════════════╪══════════
configuration │ conf │ table │ taoqi=arw/taoqi │ │
(1 row)
这可以大大简化大型 schema 的管理。
如果要授予不同对象的所有权限,我们总结如下:
- 对表授权所有权限,可以使用子句
ON ALL TABLES IN SCHEMA
- 对序列授予所有权限,可以使用子句
ON ALL SEQUENCES IN SCHEMA
- 对例程授予所以权限,可以使用子句
ON ALL ROUTINES IN SCHEMA
(类似的还有ON ALL PROCEDURES IN SCHEMA
及ON ALL FUNCTIONS IN SCHEMA
)
编程语言相关的权限
只有一个权限适用于编程语言:USAGE。此权限允许角色使用该语言。关键字 ALL 的存在是为了与其他 GRANT 和 REVOKE 语句兼容,只需应用一个权限即可。
为了防止不受信任的用户在数据库中运行代码,授予尽可能少的权限是一个很好的安全习惯。例如,要拒绝任何角色执行任何 PL/Perl 代码片段的能力,我们需要撤销特殊组 PUBLIC 的权限:
forumdb=# REVOKE USAGE ON LANGUAGE plperl FROM PUBLIC;
REVOKE
需要确保系统已安装了相应的编程语言,如果没有安装,则会报错:
forumdb=# REVOKE USAGE ON LANGUAGE plperl FROM PUBLIC; ERROR: language "plperl" does not exist
这样,即使是像 taoqi 这样的受信任用户也无法执行 PL/Perl 片段:
forumdb=> DO LANGUAGE plperl $$ elog( INFO, "Hello World" ); $$;
ERROR: permission denied for language plperl
如果我们想允许 taoqi 角色执行 PL/Perl 代码,我们需要显式授予此权限:
forumdb=# GRANT USAGE ON LANGUAGE plperl TO taoqi;
GRANT
例程相关的权限
特殊关键字 ROUTINES 包括 FUNCTIONS 和 PROCEDURES。有一个与 ROUTINES 关联的单一权限,即 EXECUTE 权限,以便能够在例程中运行(执行)代码。
为了演示上述权限,接下来我们创建一个非常简单的例程 get_max,它返回两个整数之间的最大值:
forumdb=> CREATE FUNCTION get_max (a int, b int)
RETURNS int
AS $$
BEGIN
IF a > b THEN
RETURN a;
ELSE
RETURN b;
END IF;
END
$$
LANGUAGE plpgsql;
-- 查看一下刚才创建的函数
forumdb=> \df forum.get_max
List of functions
Schema │ Name │ Result data type │ Argument data types │ Type
════════╪═════════╪══════════════════╪══════════════════════╪══════
forum │ get_max │ integer │ a integer, b integer │ func
(1 row)
现在,让我们防止除 taoqi 以外的任何角色执行这样的例程:
forumdb=> REVOKE EXECUTE ON ROUTINE get_max FROM PUBLIC;
REVOKE
forumdb=> GRANT EXECUTE ON ROUTINE get_max TO taoqi;
GRANT
如果调用该函数,除 taoqi 以外的任何角色都将收到权限拒绝错误:
-- 接下来以 james 角色执行
$ psql -U james forumdb
forumdb=> SELECT forum.get_max( 10, 20 );
ERROR: permission denied for function get_max
-- 以 taoqi 角色执行
$ psql -U taoqi forumdb
forumdb=> SELECT forum.get_max( 10, 20 );
get_max
═════════
20
(1 row)
由于 get_max 是一个函数,我们可以用 FUNCTION 关键字而不是 ROUTINE 编写 GRANT 和 REVOKE 权限。这是一个偏好问题。当我们想同时使用单个语句对模式中的所有函数和过程应用权限时,ROUTINES 关键字会变得很方便,如下所示:
-- 以 forum 角色执行
forumdb=> GRANT EXECUTE ON ALL ROUTINES IN SCHEMA forum TO taoqi;
database 相关的权限
有很多与数据库相关的权限:CONNECT 允许或拒绝连接,而不考虑基于主机的访问控制;TEMP 允许在数据库中创建临时对象(例如表);CREATE 允许在数据库中创建新对象。其授予与回收的一般的语法为:
GRANT <permission> ON DATABASE <database> TO <role>;
REVOKE <permission> ON DATABASE <database> FROM <role>;
例如,如果我们需要将每个用户锁定在数据库之外,例如,当我们必须进行维护工作时,我们可以执行以下 REVOKE 命令:
forumdb=# REVOKE CONNECT ON DATABASE forumdb FROM PUBLIC;
REVOKE
那么新的连接将因权限被拒绝而被阻挡连接:
$ psql -U taoqi forumdb
psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: FATAL: permission denied for database "forumdb"
DETAIL: User does not have CONNECT privilege.
现在,如果我们希望 taoqi 角色是唯一能够连接到数据库并创建对象而不是临时对象的角色,我们需要执行以下命令:
forumdb=# REVOKE ALL ON DATABASE forumdb FROM public;
REVOKE
forumdb=# GRANT CONNECT, CREATE ON DATABASE forumdb TO taoqi;
GRANT
授予对象所有者
我们知道对象的所有者拥有此类对象的所有可用权限。有时,我们可能希望将对象的所有权更改为另一个角色。所有权的变更是使用 ALTER 语句完成的,例如:
ALTER <object> OWNER TO <role>;
例如,要更改表的所有权,我们可以执行以下命令:
forumdb=# ALTER TABLE forum.categories OWNER TO taoqi;
ALTER TABLE
要更改函数的所有权,我们可以执行以下命令:
-- 等价于: ALTER FUNCTION forum.get_max OWNER TO taoqi;
forumdb=# ALTER ROUTINE forum.get_max OWNER TO taoqi;
ALTER ROUTINE
超级用户可以更改每个数据库对象的所有者,而普通用户却不能,它们只能修改属于它们自己权限的对象。
获取 ACL 信息
为了查看已授予角色和对象的权限,我们可以使用前面已经提到的 psql 特殊命令 \dp
(describe permission),该命令打印为特定对象(例如表)配置的 ACL。该命令对特殊 category pg_class 执行查询,该目录包含一个名为 relacl 的特定字段——一个 ACL 数组。我们可以看到如下:
forumdb=> SELECT current_role;
current_role
══════════════
forum
(1 row)
forumdb=> \dp users
Access privileges
Schema │ Name │ Type │ Access privileges │ Column privileges │ Policies
════════╪═══════╪═══════╪════════════════════════════╪════════════════════════╪══════════
forum │ users │ table │ forum=arwdDxt/forum ↵│ username: ↵│
│ │ │ forum_admins=arwdDxt/forum↵│ forum_stats=r/forum ↵│
│ │ │ taoqi=r/forum │ gecos: ↵│
│ │ │ │ forum_stats=r/forum ↵│
│ │ │ │ email: ↵│
│ │ │ │ forum_emails=r/forum │
(1 row)
forumdb=> SELECT relname, relacl FROM pg_class WHERE relname = 'users';
relname │ relacl
═════════╪════════════════════════════════════════════════════════════════
users │ {forum=arwdDxt/forum,forum_admins=arwdDxt/forum,taoqi=r/forum}
(1 row)
从上面的输出可以看出,除了输出的格式不同外,\dp
命令和查询的输出是相同的。
我们还可以使用特殊函数 aclexplode 来获取有关 ACL 含义的更多描述性信息。该函数返回一组记录,每条记录都有授予者(grantor)和被授予者(grantee)的 OID 以及授予权限的文本描述。我们可以执行以下查询:
forumdb=> WITH acl AS (
SELECT
relname,
(aclexplode(relacl)).grantor,
(aclexplode(relacl)).grantee,
(aclexplode(relacl)).privilege_type
FROM
pg_class
)
SELECT
g.rolname AS grantee,
acl.privilege_type AS permission,
gg.rolname AS grantor
FROM
acl
JOIN pg_roles g ON g.oid = acl.grantee
JOIN pg_roles gg ON gg.oid = acl.grantor
WHERE
acl.relname = 'users';
上述语句将返回分配给 users 表的所有权限,如图所示:
grantee │ permission │ grantor
══════════════╪════════════╪═════════
forum │ INSERT │ forum
forum │ SELECT │ forum
forum │ UPDATE │ forum
forum │ DELETE │ forum
forum │ TRUNCATE │ forum
forum │ REFERENCES │ forum
forum │ TRIGGER │ forum
forum_admins │ INSERT │ forum
forum_admins │ SELECT │ forum
forum_admins │ UPDATE │ forum
forum_admins │ DELETE │ forum
forum_admins │ TRUNCATE │ forum
forum_admins │ REFERENCES │ forum
forum_admins │ TRIGGER │ forum
taoqi │ SELECT │ forum
(15 rows)
简单回顾一下,前面我们说过,grantee 与 grantor 相同的话,说明该角色时对象的所有者。
总结
在本小节中,我们重点介绍了 GRANT 及 REVOKE 的使用及一些具体实例。在下面的一小节中我们再介绍 RLS 授权及如何验证。
为自己打个小广告: