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
/INSERT
、UPDATE
、DELETE
权限。加上USAGE
模式。我们可以GRANT
成为这些角色的成员:
GRANT pg_read_all_data TO my_user;
GRANT pg_write_all_data TO my_user;
这涵盖了所有基本的 DML 命令(但不包括 DDL,也不包括一些特殊命令,如 TRUNCATE
或 EXECUTE
函数权限!)。 The manual:
pg_read_all_data
读取所有数据(表、视图、序列),好像拥有
SELECT
权限 在这些对象上,以及对所有模式的USAGE
权限,即使没有 明确地拥有它。此角色没有角色属性BYPAs-s-rLS
设置。如果正在使用 RLS,管理员可能希望 将BYPAs-s-rLS
设置为该角色是GRANT
ed 的角色。
pg_write_all_data
写入所有数据(表、视图、序列),好像有
INSERT
,UPDATE
和DELETE
对这些对象的权限,以及USAGE
对这些对象的权限 所有模式,即使没有明确的。这个角色不 设置角色属性BYPAs-s-rLS
。如果正在使用 RLS,则 管理员可能希望在该角色所在的角色上设置BYPAs-s-rLS
GRANT
ed 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 开始:
对数据库对象(表、列、视图、外部表、序列、数据库、外部数据包装器、外部服务器、函数、过程、过程语言、模式或表空间)的特权
但其余部分很少需要。更多详情:
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 数据库上的用户的主要内容,如果未能解决你的问题,请参考以下文章
如果在包含架构上授予 USAGE 权限,Postgresql 将忽略缺少 EXECUTE 权限