PostgreSQL:将所有权限授予 PostgreSQL 数据库上的用户

Posted

技术标签:

【中文标题】PostgreSQL:将所有权限授予 PostgreSQL 数据库上的用户【英文标题】:PostgreSQL: Give all permissions to a user on a PostgreSQL database 【发布时间】: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。

【问题讨论】:

【参考方案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 权限,即使没有 明确地拥有它。此角色没有角色属性 BYPAs-s-rLS 设置。如果正在使用 RLS,管理员可能希望 将 BYPAs-s-rLS 设置为该角色是 GRANTed 的角色。

pg_write_all_data

写入所有数据(表、视图、序列),好像有INSERTUPDATEDELETE 对这些对象的权限,以及 USAGE 对这些对象的权限 所有模式,即使没有明确的。这个角色不 设置角色属性BYPAs-s-rLS。如果正在使用 RLS,则 管理员可能希望在该角色所在的角色上设置BYPAs-s-rLS 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。见:

Grant privileges for a particular database in PostgreSQL How to manage DEFAULT PRIVILEGES for USERs on a DATABASE vs SCHEMA?

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

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

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

Grant privileges for a particular database in PostgreSQL How to grant all privileges on views to arbitrary user

考虑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;

【讨论】:

以上是关于PostgreSQL:将所有权限授予 PostgreSQL 数据库上的用户的主要内容,如果未能解决你的问题,请参考以下文章

授予对 PostgreSQL 中未来表的权限?

授予 PostgreSQL 中特定数据库的权限

如果在包含架构上授予 USAGE 权限,Postgresql 将忽略缺少 EXECUTE 权限

PostgreSQL 和 Django 的权限被拒绝错误。授予 PostgreSQL 用户管理员权限

授予用户对 db.* 的所有权限?

在 PostgreSQL 中撤销另一个用户授予的权限