【问题标题】:PostgreSQL: Give all permissions to a user on a PostgreSQL databasePostgreSQL:将所有权限授予 PostgreSQL 数据库上的用户
【发布时间】:2014-04-24 09:08:58
【问题描述】:

我想授予用户对数据库的所有权限,而不使其成为管理员。 我想这样做的原因是,目前 DEV 和 PROD 是同一集群上的不同数据库,所以我不希望用户能够更改生产对象,但它必须能够更改 DEV 上的对象。

我试过了:

grant ALL on database MY_DB to group MY_GROUP;

但它似乎没有给予任何许可。

然后我尝试了:

grant all privileges on schema MY_SCHEMA to group MY_GROUP;

它似乎允许我创建对象但不允许查询\删除该架构上属于其他用户的对象

我可以继续向 MY_SCHEMA 上的用户授予 USAGE 权限,但它会抱怨没有表上的权限...

所以我想我的问题是:是否有任何简单的方法可以将所有权限授予数据库上的用户?

我正在开发 PostgreSQL 8.1.23。

【问题讨论】:

    标签: sql postgresql ddl privileges grant


    【解决方案1】:

    必须在连接到正确的数据库集群时执行所有命令。确保它。

    角色是数据库集群的对象。同一集群的所有数据库共享一组定义的角色。根据数据库/模式/表等授予/撤销权限。

    显然,角色需要访问数据库。默认情况下授予PUBLIC。其他:

    GRANT CONNECT ON DATABASE my_db TO my_user;
    

    Postgres 14 或更高版本的基本权限

    Postgres 14 添加了预定义的非登录角色pg_read_all_data / pg_write_all_data
    他们拥有所有表、视图和序列的SELECT/INSERTUPDATEDELETE权限。加上USAGE 模式。我们可以GRANT 成为这些角色的成员:

    GRANT pg_read_all_data TO my_user;
    GRANT pg_write_all_data TO my_user;
    

    这涵盖了所有基本的 DML 命令(但不包括 DDL,也不包括一些特殊命令,如 TRUNCATEEXECUTE 函数权限!)。 The manual:

    pg_read_all_data

    读取所有数据(表、视图、序列),好像拥有SELECT 权限 在这些对象上,以及对所有模式的USAGE 权限,即使没有 明确地拥有它。此角色没有角色属性 BYPASSRLS 设置。如果正在使用 RLS,管理员可能希望 将 BYPASSRLS 设置为该角色是 GRANTed 的角色。

    pg_write_all_data

    写入所有数据(表、视图、序列),好像有INSERTUPDATEDELETE 对这些对象的权限,以及 USAGE 对这些对象的权限 所有模式,即使没有明确的。这个角色不 设置角色属性BYPASSRLS。如果正在使用 RLS,则 管理员可能希望在该角色所在的角色上设置BYPASSRLS GRANTed to。

    不使用预定义角色的所有权限(任何 Postgres 版本)

    必须在连接到正确的数据库时执行命令。确保它。

    角色需要(至少)schema 上的USAGE 权限。同样,如果授予PUBLIC,您将获得保障。其他:

    GRANT USAGE ON SCHEMA public TO my_user;
    

    或在所有自定义架构上授予USAGE

    DO
    $$
    BEGIN
       -- RAISE NOTICE '%', (  -- use instead of EXECUTE to see generated commands
       EXECUTE (
       SELECT string_agg(format('GRANT USAGE ON SCHEMA %I TO my_user', nspname), '; ')
       FROM   pg_namespace
       WHERE  nspname <> 'information_schema' -- exclude information schema and ...
       AND    nspname NOT LIKE 'pg\_%'        -- ... system schemas
       );
    END
    $$;
    

    然后,所有的所有权限(需要 Postgres 9.0 或更高版本)。
    不要忘记序列(如果有的话):

    GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO my_user;
    GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO my_user;
    

    或者,您可以使用 "Grant Wizard" of pgAdmin 4 来使用 GUI。

    这包括现有对象的权限。要同时涵盖未来的对象,请设置DEFAULT PRIVILEGES。见:

    还有一些其他的对象,the manual for GRANT 有完整的列表。从 Postgres 14 开始:

    对数据库对象(表、列、视图、外部表、序列、数据库、外部数据包装器、外部服务器、函数、过程、过程语言、模式或表空间)的特权

    但其余部分很少需要。更多详情:

    考虑upgrading to a current version

    【讨论】:

    • 首先我使用'sudo -i -u postgres'
    • @Abhishek:使用 psql 交互式终端或将许多其他客户端程序之一连接到相关数据库。在那里,您可以在交互式会话中使用 SQL 命令。您不能只在 Linux shell 中键入 SQL 命令。
    • 记住:在运行这些命令之前,首先需要切换到psql中的数据库:\c my_db
    • 哦,这个答案非常完美,只需要澄清新创建的表等没有获得这些新特权。为此,应使用 ALTER DEFAULT PRIVILEGES... 指定它们
    • @Ivan:我添加了一些内容以使其更清晰。
    【解决方案2】:
    GRANT ALL PRIVILEGES ON DATABASE "my_db" to my_user;
    

    【讨论】:

    • 授予所有特权ON DATABASE 听起来很强大,但并没有多大作用。这只是一个开始。它不对包含的对象授予任何特权。
    【解决方案3】:

    在 PostgreSQL 9.0+ 中,您将执行以下操作:

    GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA MY_SCHEMA TO MY_GROUP;
    GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA MY_SCHEMA TO MY_GROUP;
    

    如果您也想为新创建的关系启用此功能,请设置默认权限:

    ALTER DEFAULT PRIVILEGES IN SCHEMA MY_SCHEMA
      GRANT ALL PRIVILEGES ON TABLES TO MY_GROUP;
    ALTER DEFAULT PRIVILEGES IN SCHEMA MY_SCHEMA
      GRANT ALL PRIVILEGES ON SEQUENCES TO MY_GROUP;
    

    但是,看到您使用的是 8.1,您必须自己编写代码:

    CREATE FUNCTION grant_all_in_schema (schname name, grant_to name) RETURNS integer AS $$
    DECLARE
      rel RECORD;
    BEGIN
      FOR rel IN
        SELECT c.relname
        FROM pg_class c
        JOIN pg_namespace s ON c.namespace = s.oid
        WHERE s.nspname = schname
      LOOP
        EXECUTE 'GRANT ALL PRIVILEGES ON ' || quote_ident(schname) || '.' || rel.relname || ' TO ' || quote_ident(grant_to);
      END LOOP;
      RETURN 1;
    END; $$ LANGUAGE plpgsql STRICT;
    REVOKE ALL ON FUNCTION grant_all_in_schema(name, name) FROM PUBLIC;
    

    这将设置所有关系的权限:表、视图、索引、序列等。如果你想限制它,请过滤pg_class.relkind。详情请见pg_class docs

    您应该以超级用户身份运行此函数,并根据您的应用程序的需要定期运行此函数。一种选择是将其打包到每天或每小时执行的 cron 作业中。

    【讨论】:

    • 嗨帕特里克,“所有表”在 8.1 上不可用 (postgresql.org/docs/8.1/static/sql-grant.html) 我知道我可以遍历表并单独授予权限,但这是我试图避免的。但感谢您的帮助
    • @Diego:为 8.1 添加了解决方案
    • 感谢 patrick,我最终使用了与您类似的东西,但没有使用“GRANT ALL”。由于某种原因,它似乎没有做任何事情。例如,我运行:将模式测试上的 ALL 授予 userA;但在那之后,userA 仍然无权从模式测试中的表中读取数据
    • 您应该在架构上 GRANT USAGE。然后在该模式中的所有关系(表、视图、序列、索引等)上,您必须分别 GRANT SELECT、INSERT、UPDATE、DELETE、TRUNCATE。架构是命名空间,关系是您的数据所在的位置。
    【解决方案4】:

    我执行以下操作以在 PostgreSQL 9.4.15 数据库上添加角色“eSumit”并为该角色提供所有权限:

    CREATE ROLE eSumit;
    
    GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO eSumit;
    
    GRANT ALL PRIVILEGES ON DATABASE "postgres" to eSumit;
    
    ALTER USER eSumit WITH SUPERUSER;
    

    还通过以下方式检查了 pg_table 条目:

    从 pg_roles 中选择 *;

    数据库查询快照:

    【讨论】:

    • 我有 Postgres 10.3 版,当我在数据库名称周围使用引号时会引发语法错误。
    【解决方案5】:

    在 PostgreSQL 12 及更高版本中,可以将数据库中表的所有权限授予角色/用户/帐户。

    语法是:

    GRANT ALL ON table_name TO role_name;
    

    如果您想将其授予数据库中的所有表,则语法为:

    GRANT ALL ON ALL TABLES TO role_name;
    

    如果您想将其授予数据库中某个模式的所有表,则语法为:

    GRANT ALL ON ALL TABLES IN SCHEMA schema_name TO role_name;
    

    注意:请记住,您需要先选择数据库,然后才能将其权限授予用户。

    资源PostgreSQL GRANT

    就是这样

    我希望这会有所帮助

    【讨论】:

    • GRANT USAGE ON ALL TABLES IN SCHEMA schema_name TO role_name 导致没有IN SCHEMA schema_name 的错误:ERROR: 42601: syntax error at or near "TO"
    【解决方案6】:

    将 SCHEMA 架构名称授予用户;

    【讨论】:

      【解决方案7】:
      GRANT ALL ON SCHEMA schema_name TO user_name;
      

      【讨论】:

        猜你喜欢
        • 2020-06-17
        • 1970-01-01
        • 1970-01-01
        • 2014-09-15
        • 1970-01-01
        • 1970-01-01
        • 2021-12-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多