PostgreSQL 用户及授权管理 04:授予及回收权限

news2024/11/20 10:38:58

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 privilegesColumn 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 SCHEMAON 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 typesType
════════╪═════════╪══════════════════╪══════════════════════╪══════
 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 privilegesColumn 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 授权及如何验证。

为自己打个小广告:

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1675193.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux/ubuntu build编译make时出现has modification time int the future的问题解决方法

针对Linux由于双系统之间的时间冲突导致linux时间经常变化&#xff0c;出现执行make命令时出现“make[2]: Warning: File xxx.c’ has modification time 1.6e05 s in the future “警告的问题&#xff0c;亦或者虚拟机出现相同的问题。 由于时钟同步问题&#xff0c;出现 warn…

CAST: Cross-Attention in Space and Time for Video Action Recognition

标题&#xff1a;CAST: 时空交叉注意力网络用于视频动作识别 原文链接&#xff1a;2311.18825v1 (arxiv.org)https://arxiv.org/pdf/2311.18825v1 源码链接&#xff1a;GitHub - KHU-VLL/CASThttps://github.com/KHU-VLL/CAST 发表&#xff1a;NeurIPS-2023&#xff08;CCF A…

SwiftUI 调整视图内容周围间隙(Content Margins)的“时髦”方法

概述 在 SwiftUI 开发的应用中,往往在小屏设备(比如 iPhone)上布局良好的 App 放到大屏(iPad)上后就会“一塌糊涂”。因为它们一味的只想着“占据”却不知道“舍弃”。 从 iOS 17.0(iPad 17.0)开始苹果提供了原生的视图修改器方法专注于处理此事。 在本篇博文中,您将…

MVC WebAPI

创建项目 创建api控制器 》》》 web api 控制器要继承 ApiController 》》》 数据会自动装配 及自动绑定 》》》》FromBody&#xff1a; Post请求的基础类型的参数和Get请求有点不一样&#xff0c;我们知道Get请求的参数是通过Url来传递的&#xff0c;而Post请求则是通过H…

华为涅槃,余承东重生

最近一段时间&#xff0c;余承东甚为低调。最为明显的是&#xff0c;“遥遥领先”已经听不到了&#xff0c;“余大嘴”口中的措辞越来越克制。 今后手机相关的发布会&#xff0c;或许不再看到余承东的身影。 5月10日&#xff0c;余承东的职位正式更新&#xff0c;从终端BG CE…

暴雨分布式存储集群助重庆高校打造智慧校园

教育是国家发展的基石&#xff0c;教育兴则国家兴&#xff0c;教育强则国家强。党的二十大报告指出&#xff0c;“加快建设教育强国”&#xff0c;并提出到2035年“建成教育强国”的总体目标。随着数字时代的到来&#xff0c;以物联网、大数据、云计算和人工智能为代表的数字技…

Seal^_^【送书活动第4期】——《Web渗透测试技术》

Seal^_^【送书活动第4期】——《Web渗透测试技术》 一、参与方式二、本期推荐图书2.1 前 言2.2 关于本书2.3 本书读者2.4 图书简介2.5 作者荐语2.6 编辑推荐2.7 目 录 三、正版购买 掌握Web渗透测试技术&#xff0c;提高Web应用安全性。 一、参与方式 1、关注博主的账号。 2、点…

The Quantcast File System——论文泛读

VLDB 2013 Paper 分布式元数据论文阅读笔记整理 问题 在2013年之前&#xff0c;由于网络链路带宽有限&#xff0c;数据在集群中移动速度慢&#xff0c;因此Hadoop尽量将数据留在原来的位置&#xff0c;并将处理代码发送给它。随着网络链路的发展&#xff0c;可以之前更高的数…

【多人协作】场景模拟(一)

文章目录 实现多人协作场景&#xff1a;操作流程1开发人员a和b克隆仓库到本地2在本地仓库建立分支并与远程分支建立链接3开发人员工作并提交代码4将合并dev分支与master分支 实现多人协作 多人协作开发是git的最核心也是最重要的操作。多人协作也就意味着同一时间里&#xff0…

快速传输大文件:手机电脑互传文件的最佳解决方案

无论是工作还是生活&#xff0c;我们都可能需要将照片、视频、音乐或其他类型的文件从一台设备发送到另一台设备。然而&#xff0c;由于网络速度的限制&#xff0c;传统的文件传输方法可能会非常耗时。那么&#xff0c;有没有一种快速传输大文件的解决方案呢&#xff1f;答案是…

基于IDEA快速创建一个SpringMVC项目并且配置Tomcat

1&#xff0c;打开IDEA&#xff0c;新建Maven项目【使用web模板创建】 使用社区版的同学创建普通的maven项目&#xff0c;并配置项目的webapp&#xff0c;详情可参考 快速创建一个SpringMVC项目&#xff08;IDEA&#xff09; 2&#xff0c;在main目录下创建Java和resource目录…

YOLOv9独家原创改进: 特征融合创新 | 一种基于内容引导注意力(CGA)的混合融合 | IEEE TIP 2024 浙大

💡💡💡创新点:提出了一种基于内容引导注意力(CGA)的混合融合方案,将编码器部分的低级特征与相应的高级特征有效融合。 💡💡💡在多个数据集实现暴力涨点,适用于小目标,低对比度场景 💡💡💡如何跟YOLOv9结合:将backbone和neck的特征融合,改进结构图如下…

强化训练:day9(添加逗号、跳台阶、扑克牌顺子)

文章目录 前言1. 添加逗号1.1 题目描述2.2 解题思路2.3 代码实现 2. 跳台阶2.1 题目描述2.2 解题思路2.3 代码实现 3. 扑克牌顺子3.1 题目描述3.2 解题思路3.3 代码实现 总结 前言 1. 添加逗号   2. 跳台阶   3. 扑克牌顺子 1. 添加逗号 1.1 题目描述 2.2 解题思路 我的写…

短视频最后的慢动作怎么做:成都鼎茂宏升文化传媒公司

短视频最后的慢动作怎么做&#xff1a;技巧与创意实践指南 在短视频创作的浩瀚宇宙中&#xff0c;慢动作特效如同一颗璀璨的星辰&#xff0c;为作品增添无限魅力与情感深度。它不仅能够放大细节之美&#xff0c;还能延长关键瞬间&#xff0c;引发观众强烈的情感共鸣。短视频最…

五丰黎红针对主厨开展精准营销,“星厨俱乐部”平台助力调味品快速动销。

以“质量”为核心&#xff0c;以“绿色发展”为引领&#xff0c;致力于打造中国味道的调味品企业五丰黎红&#xff0c;长期以来不断改革生产设备及创新工艺&#xff0c;已发展成为国家农&#xff08;林&#xff09;业产业化龙头企业、省卓越绩效模式先进企业、省服务业企业50强…

百度云防护设置UA拦截和测试是否生效

最近&#xff0c;有位同学反馈网站遭遇UA为“Go-http-client/1.1”恶意请求 然后设置防护模板 自定义访问策略&#xff0c;把UA包含Go-http-client的进行拦截。 然后我们再进入17测进行测试 点高级&#xff0c;user-agent栏中输入Go-http-client 测试结果反馈状态403&#xff…

【java-数据结构15-模拟实现栈的方法】

上篇文章中&#xff0c;我们已经手动实现了栈&#xff0c;下面&#xff0c;我们将继续手动实现栈的方法~ 1.在栈中存放元素 1.定义一个usedsize&#xff0c;用来临时存放下标 2.当存放一个元素后&#xff0c;下标加一 3.不要忘记判满 如图 代码如下 判满方法 public boolea…

linux 网络管理 实验

目录 网络管理主机名管理网络管理 网络管理 主机名管理 执行如下命令查看主机名。 [rootopenEuler ~]# hostname openEuler [rootopenEuler ~]# cat /etc/hostname #这个文件是主机名的配置文件 openEuler执行如下命令临时修改主机名。 [rootopenEuler ~]# hostname huawe…

【机器学习300问】81、什么是动量梯度下降算法?

动量梯度下降算法&#xff08;Momentum&#xff09;是利用指数加权移动平均的思想来实现梯度下降的算法。让我们先来回顾一下基础的梯度下降方法以及看看它有哪些不足之处。接着引出动量梯度下降算法&#xff0c;在理解了它的原理后看看它是如何规避之前方法的不足的。 如果不知…

AI如何推动科学的变革:AlphaFold的发展历程与科学范式的转变

之前我们的文章介绍了DeepMind最新的研究成果AlphaFold3&#xff0c;在近期的访谈中&#xff0c;DeepMind的科学副总裁普什梅特科利&#xff08;Pushmeet Kohli&#xff09;与斯坦福大学教授维杰潘德&#xff08;Vijay Pande&#xff09;深入讨论了人工智能&#xff08;AI&…