ERROR: permissão negada para a relação tablename no Postgres ao tentar um SELECT como um usuário somente leitura


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

O usuário somente leitura pode se conectar, ver as tabelas, mas quando tenta fazer uma seleção simples, obtém:

ERROR: permission denied for relation mytable
SQL state: 42501

Isso está acontecendo no PostgreSQL 9.1

O que eu fiz de errado?


1
Você pode fornecer alguns detalhes sobre "relação mytable"? Esquema, é uma tabela "real" (ou uma visão / função), aciona ...
— Igor Romanchenko

Respostas:


161

Aqui está a solução completa para PostgreSQL 9+, atualizada recentemente.

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;

Agradecemos a https://jamie.curle.io/creating-a-read-only-user-in-postgres/ por vários aspectos importantes

Se alguém encontrar um código mais curto, e de preferência um que seja capaz de fazer isso para todos os bancos de dados existentes, elogios extras.


6
isso inclui visualizações?
— Frank Conry

9
Por que você está dando GRANT ALLpermissão por padrão ao usuário somente leitura?
— Slava Fomin II

1
dei exatamente como está definido, ainda o erro Sam
— Anish Gopinath

pode confirmar os direitos concedidos usando \ddp. Deve mostrar apenas =r/como granting_user=r/readonly_userapenas acesso de leitura.
— Greg Bray

Este é o SQL literal da pergunta. Não vejo como isso fornece uma solução.
— r351574nc3

12

Tente adicionar

GRANT USAGE ON SCHEMA public to readonly;

Você provavelmente não sabia que é necessário ter as permissões necessárias para um esquema, a fim de usar objetos no esquema.


Algo estranho está acontecendo, eu executo esses comandos no servidor usando psqlcomo postgresusuário e obtenho uma resposta adequada GRANT,. Ainda assim, quando olho para a ACL nas tabelas, vejo apenas duas outras contas, uma sendo o proprietário do banco de dados jirausere outra conta somente leitura chamada qauser. Mas o meu readonlynão aparece lá. Postgres é a versão 9.1 e até reiniciei o servidor, ainda não acontece nada.
— Sorin

2
qual é / foi a saída de \ du no console psql? Você ainda pode fornecer esta saída ou ela já está corrigida como na sua resposta?
— sufleR de

Não sei bem o que aconteceu, pois o resultado estava correto (GRANT). Ontem não funcionou, mas hoje funcionou depois de executar, novamente, todos os 3 comandos.
— sorin

3
Observação: a resposta esperada para isso é simplesmente 'GRANT'. Se você vir 'AVISO: nenhum privilégio foi concedido para "público"', então NÃO funcionou. O usuário somente leitura não pode conceder a si mesmo permissões extras. Apenas um usuário com permissões 'GRANT' pode fazer isso, então você provavelmente precisa fazer login como um superusuário.
— PeterVermont

Oi, quando tento GRANT SELECT EM TODAS AS TABELAS NO SCHEMA public TO postgres; responde: ERROR: permissão negada para o databasechangeloglock da relação. Você sabe o que estou fazendo de errado? Obrigado (acontece no GAppEngine Posgres9.6 usando o endereço público e acessando pelo terminal)
— Mike

-5

Isso funcionou para mim:

Verifique a função atual na qual você está conectado usando: SELECT CURRENT_USER, SESSION_USER;

Observação : ele deve corresponder ao proprietário do esquema.

Schema | Nome Tipo | Proprietário
-------- + -------- + ------- + ----------

Se o proprietário for diferente, conceda todas as concessões à função de usuário atual da função de administrador ao:

GRANT 'ROLE_OWNER' para 'CURRENT ROLENAME';

Em seguida, tente executar a consulta, ela dará a saída, pois agora tem acesso a todas as relações.


5
Alterar o proprietário para um usuário chamado readonly dificilmente soa como a solução certa.
— Anna

Dependendo do seu caso, o dono da mesa errado pode ser a causa (era meu inimigo). Maneira adequada de alterar o proprietário da tabela no PostgreSQL: consulte stackoverflow.com/a/13535184
— tanius

-6

certifique-se de que seu usuário tenha atributos em sua função. por exemplo:

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

depois de executar o seguinte comando:

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 | {}

resolveu o problema.

veja o tutorial para funções e outras coisas aqui: https://www.digitalocean.com/community/tutorials/how-to-use-roles-and-manage-grant-permissions-in-postgresql-on-a-vps--2


18
Não! Atribuir a função de superusuário a um usuário chamado "somente leitura" para fazer uma "seleção" não é a solução correta.
— Anna

@Anna Não é isso que está acontecendo aqui. Este tópico não é sobre fornecer acesso somente leitura. Este tópico é sobre como dar a um usuário acesso para dar a outro usuário acesso somente leitura. IMHO, isso está correto. Se o seu usuário não for um Superusuário, você não poderá criar um usuário somente leitura. O erro que está ERROR: permission denied for relation mytable
— ocorrendo

-7

Você deve executar a próxima consulta:

GRANT ALL ON TABLE mytable TO myuser;

Ou se o seu erro está em uma visualização, talvez a tabela não tenha permissão, então você deve executar a próxima consulta:

GRANT ALL ON TABLE tbm_grupo TO myuser;

5
O usuário é denominado "somente leitura". É duvidoso que dar ao usuário todas as permissões seja o objetivo. Ele só quer fazer uma seleção.
— Anna

Isso anula o propósito de nomear o usuário 'ReadOnly' se você estiver dando ALTER DROP DELETEEct. Para aquele usuário ...
— JayRizzo
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.