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?

Sorin
fonte
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.

Sorin
fonte
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.

sufleR
fonte
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.

Dhwani Shah
fonte
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

PuN1sh3r
fonte
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;
sim
fonte
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