暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

社区博客 | 消除关于 PostgreSQL 默认权限的神话

点击上方蓝字关注我们





导读

ALTER DEFAULT PRIVILEGES 命令允许我们设置将应用于将来创建的对象的权限。请务必注意,这不会影响分配给现有对象的权限;可以为在当前数据库或指定架构中创建的对象全局设置默认权限。


数据库用户对默认权限的行为存在许多误解,我经常听到抱怨说,即使在为特定架构分配了默认权限后,用户也无权访问。在本篇博客中,我们将澄清这些关于 PostgreSQL 中默认权限的疑问。


原文作者:Anil Joshi


关键词:PostgreSQL、默认权限


01 
了解默认权限

创建对象时,会为其分配一个所有者。最初,owner 是执行 create object 语句(以后可以更改)的角色。对于大多数类型的对象,只有所有者(或超级用户)拥有对象的所有权限。但是,可以通过使用 ALTER DEFAULT PRIVILEGES 语句更改默认权限来更改此行为。这允许我们默认将任何权限分配给任何类型对象上的任何目标用户。目前,只有 schema、table(包括视图和外部表)、sequence、functions 和 type(包括domains)的权限可以使用 ALTER DEFAULT PRIVILEGES 来更改。

例:
    demodb=# SELECT current_user;
    current_user
    --------------
    postgres
    (1 row)
    demodb=# CREATE SCHEMA test;
    CREATE SCHEMA
    demodb=# GRANT USAGE ON SCHEMA test TO obj_user;
    GRANT
    demodb=# CREATE TABLE test.city(id int, name varchar);
    CREATE TABLE
    demodb=# INSERT INTO test.city VALUES(1,'Mumbai');
    INSERT 0 1

    现在测试角色 obj_user 的权限:
      demodb=# SET ROLE obj_user;
      SET
      demodb=> SELECT * FROM test.city;
      ERROR: permission denied for table city

      需要显式授予权限:
        demodb=> SET ROLE postgres;
        SET
        demodb=# GRANT SELECT ON TABLE test.city TO obj_user;
        GRANT
          demodb=# SET ROLE obj_user;
          SET
          demodb=> SELECT * FROM test.city;
          id | name
          ----+--------
          1 | Mumbai
          (1 row)

          在上面的例子中,用户 obj_user 默认没有获得 SELECT 权限,我们必须显式授予该权限。如果始终如此,我们应该考虑自动执行该过程,以授予对测试架构中表的 SELECT 权限。这可以通过 ALTER DEFAULT PRIVILEGES 实现。


          02 
          设置默认权限

          让我们授予默认权限并再次测试对新对象的访问权限:

            demodb=# SELECT current_user;
            current_user
            --------------
            postgres
            (1 row)
            demodb=# ALTER DEFAULT PRIVILEGES IN SCHEMA test GRANT SELECT ON TABLES TO obj_user;
            ALTER DEFAULT PRIVILEGES
            demodb=# CREATE TABLE test.state(id int, name varchar);
            CREATE TABLE
            demodb=# INSERT INTO test.state VALUES(1,'Maharashtra');
            INSERT 0 1
              demodb=# SET ROLE obj_user;
              SET
              demodb=> SELECT * FROM test.state;
              id | name
              ----+-------------
              1 | Maharashtra
              (1 row)

              权限按预期工作。现在,让我们考虑使用与 postgres 不同的用户创建一个对象。让我们与另一个用户 obj_creator 一起创建一个表,并测试obj_user的权限:
                demodb=> SET ROLE obj_creator;
                SET
                demodb=> CREATE TABLE test.nationality(id int, name varchar);
                CREATE TABLE
                demodb=> INSERT INTO test.nationality VALUES(1,'Indian');
                INSERT 0 1
                  demodb=> SET ROLE obj_user;
                  SET
                  demodb=> SELECT * FROM test.nationality;
                  ERROR: permission denied for table nationality
                  没用!!这是我们授予的 PostgreSQL 默认权限的实际行为。许多用户认为,由于我们授予了默认权限,因此无论对象创建者是谁,它都将始终有效。


                  03 
                  它不起作用的原因


                  在这里,用户obj_user不会自动获得对新创建的表的权限,因为默认权限仅在对象创建者与语句的执行者相同(默认情况下,当前用户,在本例中为 postgres)时有效。ALTER DEFAULT PRIVILEGES




                  04 
                  解开迷思

                  为了解决这个问题,让我们执行以下语句,考虑到 obj_creator 将是测试架构中对象的创建者:
                    demodb=# SELECT current_user;
                    current_user
                    --------------
                    postgres
                    (1 row)
                    demodb=# ALTER DEFAULT PRIVILEGES IN SCHEMA test FOR ROLE obj_creator GRANT SELECT ON TABLES to obj_user;
                    ALTER DEFAULT PRIVILEGES
                      demodb=# set role obj_creator;
                      SET
                      demodb=> create table test.citizen(id int, name varchar);
                      CREATE TABLE
                      demodb=> insert into test.citizen values(1, 'David');
                      INSERT 0 1

                      现在测试 obj_user 的访问权限:
                        demodb=> set role obj_user;
                        SET
                        demodb=> select * from test.citizen;
                        id | name
                        ----+-------
                        1 | David
                        (1 row)

                        成功了!通过在 ALTER DEFAULT PRIVILEGES 语句中指定对象创建者,我们确保obj_user自动获得 obj_creator 在测试架构中创建的任何新表的 SELECT 权限。


                        05 
                        更多示例语句

                          ALTER DEFAULT PRIVILEGES IN SCHEMA test FOR ROLE obj_creator GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO obj_user;
                          ALTER DEFAULT PRIVILEGES IN SCHEMA test FOR ROLE obj_creator GRANT USAGE ON TYPES TO obj_user;
                          ALTER DEFAULT PRIVILEGES IN SCHEMA test FOR ROLE obj_creator GRANT EXECUTE ON FUNCTIONS TO obj_user;
                          ALTER DEFAULT PRIVILEGES IN SCHEMA test FOR ROLE obj_creator GRANT SELECT ON SEQUENCES TO obj_user;
                          ALTER DEFAULT PRIVILEGES FOR ROLE obj_creator GRANT USAGE ON SCHEMAS TO obj_user;

                          同样,就像 GRANT 一样,我们也可以撤销权限。


                          06 
                          REVOKE 语句示例

                            ALTER DEFAULT PRIVILEGES IN SCHEMA test FOR ROLE obj_creator REVOKE INSERT,UPDATE,DELETE ON TABLES FROM obj_user;
                            ALTER DEFAULT PRIVILEGES IN SCHEMA test FOR ROLE obj_creator REVOKE USAGE ON types FROM obj_user;
                            ALTER DEFAULT PRIVILEGES IN SCHEMA test FOR ROLE obj_creator REVOKE execute ON functions FROM obj_user;
                            ALTER DEFAULT PRIVILEGES IN SCHEMA test FOR ROLE obj_creator REVOKE SELECT ON sequences FROM obj_user;
                            ALTER DEFAULT PRIVILEGES FOR ROLE obj_creator REVOKE USAGE ON SCHEMAS FROM obj_user;


                            07 
                            列出默认权限

                            在 PostgreSQL 中,ddp 命令可用于列出默认权限。
                              demodb=# ddp
                              Default access privileges
                              Owner | Schema | Type | Access privileges
                              -------------+--------+-------+------------------------
                              obj_creator | test | table | obj_user=r/obj_creator
                              postgres | test | table | obj_user=r/postgres
                              (2 rows)

                              或者可以使用以下查询以更具可读性的方式返回输出。
                                demodb=# SELECT
                                defaclnamespace::regnamespace AS schema,
                                CASE defaclobjtype WHEN 'r' THEN 'table' WHEN 'S' THEN 'sequence' WHEN 'T' THEN 'type' WHEN 'n' THEN 'schema' END AS obj_type,
                                (aclexplode(defaclacl)).privilege_type AS privilege_type,
                                (aclexplode(defaclacl)).grantor::regrole AS for_role,
                                (aclexplode(defaclacl)).grantee::regrole AS to_user
                                FROM pg_default_acl;
                                schema | obj_type | privilege_type | for_role | to_user
                                --------+----------+----------------+-------------+----------
                                test | table | SELECT | postgres | obj_user
                                test | table | SELECT | obj_creator | obj_user
                                (2 rows)

                                使用 ALTER DEFAULT PRIVILEGES


                                在许多情况下,我们可能希望为特定角色创建的对象设置默认权限。FOR ROLE cause 在多个角色创建对象且每个角色都有自己的一组具有特定访问要求的用户的环境中特别有用。使用 ALTER DEFAULT PRIVILEGES,我们可以自动化和简化权限管理,确保正确的用户无需人工干预即可访问新对象。


                                原文作者:Sagar Jadhav
                                原文链接:
                                https://www.percona.com/blog/dispelling-myths-about-postgresql-default-privileges/


                                END

                                为促进团队内外的沟通联系,我们Klustron团队的bbs论坛开始上线,欢迎各位同学使用!链接:https://forum.klustron.com/,或者点击文末“阅读原文”,即可跳转

                                论坛目前是测试版,可能还存在不稳定的现象,欢迎各位老师、朋友共享信息,如果遇到问题还请谅解。

                                欢迎大家下载和安装Klustron数据库集群,并免费使用(无需注册码)

                                Klustron 完整软件包下载:
                                http://downloads.klustron.com/

                                如需购买请邮箱联系sales_vip@klustron.com,有相关问题欢迎添加下方小助手微信联系🌹

                                产品文档

                                Klustron 快速入门:
                                https://doc.klustron.com/zh/Klustron_Instruction_Manual.html

                                Klustron 快速体验指南:
                                https://doc.klustron.com/zh/Klustron_Quickly_Guide.html

                                Klustron 功能体验范例:
                                https://doc.klustron.com/zh/Klustron-function-experience-example.html

                                Klustron 产品使用和测评指南:
                                https://doc.klustron.com/zh/product-usage-and-evaluation-guidelines.html


                                 点击👆上方,关注获取源代码及技术信息~










                                文章转载自KunlunBase 昆仑数据库,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                                评论