授予 PostgreSQL 中特定数据库的权限
Posted
技术标签:
【中文标题】授予 PostgreSQL 中特定数据库的权限【英文标题】:Grant privileges for a particular database in PostgreSQL 【发布时间】:2014-09-15 02:28:00 【问题描述】:我正在从 mysql 迁移到 PostgreSQL,并且遇到了用户权限问题。我习惯于使用以下命令为用户分配数据库的所有表的所有权限:
# MySQL
grant all privileges on mydatabase.* to 'myuser'@'localhost' identified by 'mypassword';
在我看来,PostgreSQL 9.x 解决方案涉及将权限分配给“模式”,但我需要努力弄清楚要发出什么 SQL 证明是多余的。我知道再花几个小时的研究会得出一个答案,但我认为每个从 MySQL 迁移到 PostgreSQL 的人都可以受益于在 Web 上至少有一个页面提供简单而完整的配方。这是我需要为用户发出的唯一命令。我宁愿不必为每个新表发出命令。
我不知道在 PostgreSQL 中必须以不同的方式处理哪些场景,所以我将列出一些我过去通常必须处理的场景。假设我们只是想修改已经创建的单个数据库的权限。
(1a) 尚未创建所有表,或 (1b) 已创建表。
(2a) 用户尚未创建,或 (2b) 用户已创建。
(3a) 权限尚未分配给用户,或 (3b) 权限之前已分配给用户。
(4a) 用户只需要插入、更新、选择和删除行,或者 (4b) 用户还需要能够创建和删除表。
我已经看到了授予所有数据库所有权限的答案,但这不是我想要的。拜托,我正在寻找一个简单的食谱,虽然我也不介意解释。
我不想向所有用户和所有数据库授予权限,这似乎是传统的捷径,因为当任何一个用户受到威胁时,这种方法会危及所有数据库。我托管多个数据库客户端并为每个客户端分配不同的登录名。
看起来我还需要USAGE
权限来获取serial
列的递增值,但我必须按某种顺序授予它。我的问题变得更复杂了。
【问题讨论】:
我怀疑 PostgresQL 上用户权限的复杂性可能会严重阻碍更广泛的采用。 以下页面似乎授予用户对所有数据库的所有表的必要权限,而我只想授予对单个数据库的权限。 dba.stackexchange.com/questions/36870/… 【参考方案1】:Postgres 中的基本概念
角色是可以访问数据库集群中所有数据库的全局对象 - 给定所需的权限。
一个集群包含许多数据库,其中包含许多模式。不同数据库中的模式(即使名称相同)是不相关的。为架构授予权限仅适用于当前数据库(授予时的当前数据库)中的此特定架构。
默认情况下,每个数据库都以架构 public
开头。这是一个约定,许多设置都是从它开始的。除此之外,架构public
只是一个和其他架构一样的架构。
来自 MySQL,您可能希望从单个架构 public
开始,有效地完全忽略架构层。我经常在每个数据库中使用几十个模式。
Schema 有点(但不完全)像文件系统中的目录。
一旦你使用了多个模式,一定要了解search_path
设置:
默认权限
Per documentation on GRANT
:
PostgreSQL 在某些类型的对象上授予默认权限以
PUBLIC
。PUBLIC
默认不会在表上授予任何权限, 列、模式或表空间。对于其他类型,默认 授予PUBLIC
的权限如下:CONNECT
和CREATE TEMP TABLE
用于数据库;EXECUTE
函数特权;和USAGE
语言特权。
所有这些默认值都可以通过ALTER DEFAULT PRIVILEGES
进行更改:
组角色
Like @Craig commented,最好将GRANT
权限赋予一个组角色,然后使特定用户成为该角色的成员(GRANT
将组角色赋予用户角色)。这种方式更容易处理和撤销某些任务所需的特权包。
组角色只是另一个无需登录的角色。添加登录以将其转换为用户角色。更多:
Why did PostgreSQL merge users and groups into roles?预定义角色
更新: Postgres 14 或更高版本添加了新的predefined roles(正式为“默认角色”)pg_read_all_data
和pg_write_all_data
以简化以下部分内容。见:
食谱
说,我们有一个新数据库mydb
,一个组mygrp
,和一个用户myusr
...
以超级用户身份连接到相关数据库时(例如postgres
):
REVOKE ALL ON DATABASE mydb FROM public; -- shut out the general public
GRANT CONNECT ON DATABASE mydb TO mygrp; -- since we revoked from public
GRANT USAGE ON SCHEMA public TO mygrp;
像你写的那样分配“一个用户对所有表的所有权限”(我可能更严格):
GRANT ALL ON ALL TABLES IN SCHEMA public TO mygrp;
GRANT ALL ON ALL SEQUENCES IN SCHEMA public TO mygrp; -- don't forget those
要为未来的对象设置默认权限,请为在此架构中创建对象的每个角色运行:
ALTER DEFAULT PRIVILEGES FOR ROLE myusr IN SCHEMA public
GRANT ALL ON TABLES TO mygrp;
ALTER DEFAULT PRIVILEGES FOR ROLE myusr IN SCHEMA public
GRANT ALL ON SEQUENCES TO mygrp;
-- more roles?
现在,将组授予用户:
GRANT mygrp TO myusr;
相关答案:
PostgreSQL - DB user should only be allowed to call functions替代(非标准)设置
来自 MySQL,并且由于您希望将数据库的权限分开,您可能会喜欢这种非标准设置 db_user_namespace
。 Per documentation:
此参数启用每个数据库的用户名。默认关闭。
仔细阅读手册。我不使用这个设置。它不会使上述内容无效。
【讨论】:
不值得单独回答,但我还想补充一点,一般来说,您不应该对个人用户使用GRANT
ing。而是创建角色(组)并授予他们对表的权限。创建用户时将用户添加到角色。这将为您节省很多管理上的痛苦。
@CraigRinger:没错。这是与演示代码相关的答案:***.com/questions/15867175/…
@ErwinBrandstetter,您的修订接近于澄清我的另一个问题。为什么在“ALTER DEFAULT PRIVILEGES”查询中提到“myusr”?在我看来,“GRANT mygrp TO myusr”应该足以授予 myusr mygrp 的权限。
@JoeLapp:只要只有一个用户,你就根本不需要ALTER DEFAULT PRIVILEGES
。如果有多个,并且每个都可以创建对象,并且您希望其他用户共享新对象的权限,请自动授予组角色权限。
只是想添加一个说明。默认情况下,在数据库中创建资源的用户拥有对该资源的所有权限。 ALTER DEFAULT PRIVILEGES
的目的是让其他用户也可以访问该资源。在此示例中,这是通过向mygrp
授予myusr
创建的所有资源的权限来完成的。 AWS 文档有一句话让我很清楚:“定义一组默认访问权限,以应用于将来由指定用户创建的对象”(我的重点)。 docs.aws.amazon.com/redshift/latest/dg/…【参考方案2】:
我不想向所有用户和所有数据库授予权限,这似乎是传统的捷径,因为当任何一个用户受到威胁时,这种方法会危及所有数据库。我托管多个数据库客户端并为每个客户端分配不同的登录名。
好的。当您将表分配给正确的角色时,授予的权限将是特定于角色的,而不是针对所有用户的!然后您可以决定将roles
提供给谁。
-
为每个数据库创建一个
role
。一个角色可以拥有多个用户。
然后将client-username
分配给正确的角色。
如果需要,还可以将 your-username
分配给每个角色。
(1a) 尚未创建所有表,或 (1b) 已创建表。
好的。您可以稍后创建表格。
准备好后,将表分配给正确的客户端 role
。
CREATE TABLE tablename();
CREATE ROLE rolename;
ALTER TABLE tablename OWNER TO rolename;
(2a) 用户尚未创建,或 (2b) 用户已创建。
好的。准备好后创建用户名。如果您的客户需要多个用户名,只需创建第二个 client-username
。
CREATE USER username1;
CREATE USER username2;
(3a) 权限尚未分配给用户,或 (3b) 权限之前已分配给用户。
好的。当您准备好授予权限时,创建用户并为她分配正确的角色。 使用 GRANT-TO 命令为用户分配角色。
GRANT rolename TO username1;
GRANT rolename TO username2;
(4a) 用户只需要插入、更新、选择和删除行,或者 (4b) 用户还需要能够创建和删除表。
好的。您可以运行这些命令来为您的用户添加权限。
GRANT SELECT, UPDATE, INSERT, DELETE ON dbname TO role-or-user-name;
ALTER USER username1 CREATEDB;
【讨论】:
【参考方案3】:也许您可以给我一个授予特定用户的示例 在所有表上选择/插入/更新/删除——那些现有的和不存在的 尚未创建——特定数据库?
您在 MySQL 中所称的数据库更类似于 PostgreSQL 架构,而不是 PostgreSQL 数据库。
以超级用户身份连接到数据库“test”。这里是
$ psql -U postgres test
Change the default privileges 用于现有用户“tester”。
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT INSERT, SELECT, UPDATE, DELETE ON TABLES
TO tester;
更改默认权限对现有表没有影响。这是设计使然。对于现有表,请使用标准 GRANT 和 REVOKE 语法。
您不能为不存在的用户分配权限。
【讨论】:
我认为这是我的问题之一:假设 MySQL 和 PostgreSQL 数据库是类似的实体。您的解释与 Erwin 的解释相结合,纠正了这种误解。谢谢!【参考方案4】:如果您只使用 PUBLIC,您可能会忘记架构。 然后你做这样的事情:(see doc here)
GRANT SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER
[, ...] | ALL [ PRIVILEGES ]
ON [ TABLE ] table_name [, ...]
| ALL TABLES IN SCHEMA schema_name [, ...]
TO [ GROUP ] role_name | PUBLIC [, ...] [ WITH GRANT OPTION ]
【讨论】:
谢谢,但是如果我使用 PUBLIC,我不是授予所有用户对所有数据库的特定权限吗?我希望授予单个用户对单个数据库的所有表的权限,甚至是尚未创建的表。 我说的是公共架构,而不是公共角色。 对不起,我想我不明白您的回复。也许您可以给我一个示例,该示例授予特定用户对特定数据库的所有表(现有但尚未创建的表)的选择/插入/更新/删除?谢谢!以上是关于授予 PostgreSQL 中特定数据库的权限的主要内容,如果未能解决你的问题,请参考以下文章