Postgres中,作为只读用户尝试进行SELECT操作时出现“ERROR: permission denied for relation tablename”的错误提示。

95
GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonly;

只读用户可以连接数据库,查看表格。但是当它尝试执行简单的查询时,会收到以下错误信息:

ERROR: permission denied for relation mytable
SQL state: 42501

这是在 PostgreSQL 9.1 上发生的。

我做错了什么?


1
您能提供一些关于 "relation mytable" 的详细信息吗?它是一个“真正”的表(还是视图/函数),模式,触发器... - Ihor Romanchenko
5个回答

173

这里是最近更新的适用于PostgreSQL 9+的完整解决方案。

CREATE USER readonly  WITH ENCRYPTED PASSWORD 'readonly';
GRANT USAGE ON SCHEMA public to readonly;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO readonly;

-- repeat code below for each database:

GRANT CONNECT ON DATABASE foo to readonly;
\c foo
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO readonly; --- this grants privileges on new tables generated in new database "foo"
GRANT USAGE ON SCHEMA public to readonly; 
GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonly;

感谢https://jamie.curle.io/creating-a-read-only-user-in-postgres/在几个重要方面的帮助。

如果有人发现更短的代码,并且最好能够对所有现有数据库执行此操作,那就更好了。


6
包括观点吗? - Frank Conry
9
为什么默认情况下会给只读用户授予GRANT ALL权限? - Slava Fomin II
1
我完全按照定义给出,仍然出现相同的错误。 - Anish Gopinath
可以使用\ddp确认授予的权限。应该只显示=r/,例如granting_user=r/readonly_user表示只有只读访问权限。 - Greg Bray
这是来自问题的逐字逐句的SQL语句。我不明白它如何提供解决方案。 - r351574nc3

16

尝试添加

GRANT USAGE ON SCHEMA public to readonly;

你可能不知道,要使用模式中的对象,需要拥有该模式的必要权限。


发生了一些奇怪的事情,我使用 psql 作为 postgres 用户在服务器上运行这些命令,并且确实得到了正确的响应,即 GRANT。但是,当我查看表上的 ACL 时,我只看到另外两个帐户,一个是数据库所有者 jirauser,另一个是名为 qauser 的只读帐户。但我的 readonly 并未出现在其中。Postgres 版本为 9.1,我甚至重新启动了服务器,但仍然没有任何变化。 - sorin
2
在psql控制台中,\du的输出是什么?您是否仍然可以提供此输出,或者像您的答案一样已经固定了? - sufleR
我不太清楚发生了什么事情,因为输出是正确的(GRANT)。昨天它没有工作,但今天在运行所有三个命令后它工作了。 - sorin
3
注意:对此的预期回复只需简单回答“GRANT”。如果您看到“警告:未授予“public”的任何权限”,则表示操作失败。只有具有“GRANT”权限的用户才能向自己授予额外的权限。因此,您可能需要以超级用户身份登录。 - PeterVermont
嗨,当我尝试在公共模式下授予所有表的SELECT权限给postgres时,它会响应:ERROR: permission denied for relation databasechangeloglock。你知道我做错了什么吗?谢谢(这发生在使用公共地址通过终端访问GAppEngine Posgres9.6时)。 - Mike
显示剩余2条评论

-5

这对我有用:

通过使用以下命令检查您当前登录的角色: SELECT CURRENT_USER, SESSION_USER;

注意:它必须与模式的所有者匹配。

模式 | 名称 | 类型 | 所有者
--------+--------+-------+----------

如果所有者不同,则通过以下方式将所有授权从管理员角色授予给当前用户角色:

GRANT 'ROLE_OWNER' to 'CURRENT ROLENAME';

然后尝试执行查询,现在它将访问所有关系并输出结果。


5
将所有者更改为名为“readonly”的用户似乎并不是正确的解决方法。 - Anna
根据您的情况,错误的表所有者确实可能是原因(对我来说就是这样)。在PostgreSQL中更改表所有权的正确方法:请参见https://dev59.com/C3M_5IYBdhLWcg3wgzdl#13535184。 - tanius

-7

确保您的用户在其角色上具有属性。例如:

postgres=# \du
                             List of roles
 Role name |                   Attributes                   | Member of 
-----------+------------------------------------------------+-----------
 flux      |                                                | {}
 postgres  | Superuser, Create role, Create DB, Replication | {}

执行以下命令后:
postgres=# ALTER ROLE flux WITH Superuser;
ALTER ROLE
postgres=# \du
                             List of roles
 Role name |                   Attributes                   | Member of 
-----------+------------------------------------------------+-----------
 flux      | Superuser                                      | {}
postgres  | Superuser, Create role, Create DB, Replication | {}

它修复了这个问题。

在此处查看有关角色和其他内容的教程:https://www.digitalocean.com/community/tutorials/how-to-use-roles-and-manage-grant-permissions-in-postgresql-on-a-vps--2


19
不!将超级用户角色授予名为“readonly”的用户以执行“select”操作并非正确的修复方法。 - Anna
@Anna 这里发生的不是那样的情况。这个线程不是关于赋予只读权限的。这个线程是关于赋予一个用户赋予另一个用户只读访问权限。依我之见,这是正确的。如果你的用户不是超级用户,你就不能创建只读用户。遇到的错误是由于无法创建只读用户而导致的 ERROR: permission denied for relation mytable - r351574nc3

-8

你应该执行下一个查询:

GRANT ALL ON TABLE mytable TO myuser;

如果您的错误出现在视图中,那么可能是因为该表没有权限,所以您应该执行下一个查询:

GRANT ALL ON TABLE tbm_grupo TO myuser;

6
该用户被称为“readonly”。给予该用户所有权限的目标存在疑问。他只想执行选择操作。 - Anna
1
如果你给 'ReadOnly' 用户授予 ALTER DROP DELETE 等权限的话,这就使得给用户命名为“只读”失去了意义。 - JayRizzo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接