EROR: izin ditolak untuk nama-nama relasi di Postgres ketika mencoba SELECT sebagai pengguna hanya-baca

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

Pengguna readonly dapat terhubung, melihat tabel tetapi ketika mencoba melakukan pilihan sederhana ia mendapat:

ERROR: permission denied for relation mytable
SQL state: 42501

Ini terjadi di PostgreSQL 9.1

Apa yang saya lakukan salah?

sorin
sumber
1
Dapatkah Anda memberikan beberapa detail tentang "relasi mytable"? Skema, apakah itu tabel "nyata" (atau tampilan / fungsi), memicu ...
Igor Romanchenko

Jawaban:

162

Berikut adalah solusi lengkap untuk PostgreSQL 9+, diperbarui baru-baru ini.

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;

Terima kasih kepada https://jamie.curle.io/creating-a-read-only-user-in-postgres/ untuk beberapa aspek penting

Jika ada yang menemukan kode yang lebih pendek, dan lebih disukai yang mampu melakukan ini untuk semua database yang ada, pujian ekstra.

sorin
sumber
6
apakah ini termasuk pandangan?
Frank Conry
9
Mengapa Anda memberikan GRANT ALLizin secara default kepada pengguna hanya-baca?
Slava Fomin II
1
saya memberikan persis seperti yang didefinisikan, masih kesalahan yang sama
Anish Gopinath
dapat mengkonfirmasi hak yang diberikan menggunakan \ddp. Harus menunjukkan =r/seperti granting_user=r/readonly_useruntuk akses hanya baca.
Greg Bray
Ini adalah SQL verbatim dari pertanyaan. Saya tidak melihat bagaimana ini memberikan solusi.
r351574nc3
12

Coba tambahkan

GRANT USAGE ON SCHEMA public to readonly;

Anda mungkin tidak menyadari bahwa seseorang harus memiliki izin yang diperlukan untuk skema, untuk menggunakan objek dalam skema.

sufleR
sumber
Sesuatu yang aneh terjadi, saya menjalankan perintah ini di server menggunakan psqlsebagai postgrespengguna dan saya mendapatkan respons yang tepat , GRANT. Namun, ketika saya melihat ACL di tabel, saya hanya melihat dua akun lainnya, satu adalah pemilik basis data jirauserdan satu lagi akun hanya-baca bernama qauser. Tapi saya readonlytidak muncul di sana. Postgres adalah versi 9.1 dan saya bahkan me-restart server, tetap tidak ada yang terjadi.
sorin
2
apa / adalah keluaran dari \ du di konsol psql? Apakah Anda masih dapat memberikan output ini atau sudah diperbaiki seperti pada jawaban Anda?
sufleR
Saya tidak begitu tahu apa yang terjadi, karena hasilnya benar (GRANT). YEsterday itu tidak berfungsi, tetapi hari ini berfungsi setelah menjalankan, sekali lagi, semua 3 perintah.
sorin
3
Catatan: Tanggapan yang diharapkan untuk ini hanyalah 'GRANT'. Jika Anda melihat 'PERINGATAN: tidak ada hak istimewa yang diberikan untuk "publik"' maka itu TIDAK berfungsi. Pengguna hanya-baca tidak dapat memberikan izin tambahan untuk dirinya sendiri. Hanya pengguna dengan izin 'GRANT' yang dapat melakukannya, jadi Anda mungkin perlu masuk sebagai pengguna super.
PeterVermont
Hai, ketika saya mencoba GRANT SELECT ON ALL TABLES IN SCHEMA public TO postgres; itu merespon: ERROR: izin ditolak untuk relasi databasechangeloglock. Apakah Anda tahu apa yang saya lakukan salah? Terima kasih (ini terjadi di GAppEngine Posgres9.6 menggunakan alamat publik dan mengakses melalui terminal)
Mike
-5

Ini berhasil untuk saya:

Periksa peran saat ini Anda masuk dengan menggunakan: SELECT CURRENT_USER, SESSION_USER;

Catatan : Ini harus cocok dengan Pemilik skema.

Skema | Nama | Ketik | Pemilik
-------- + -------- + ------- + ----------

Jika pemiliknya berbeda, berikan semua hibah kepada peran pengguna saat ini dari peran admin dengan:

GRANT 'ROLE_OWNER' menjadi 'CURRENT ROLENAME';

Kemudian coba jalankan kueri, itu akan memberikan output karena memiliki akses ke semua relasi sekarang.

Dhwani Shah
sumber
5
Mengubah pemilik menjadi pengguna yang disebut hanya baca bukanlah perbaikan yang tepat.
Anna
Bergantung pada kasus Anda, pemilik meja yang salah memang bisa menjadi penyebabnya (itu musuh saya). Cara yang tepat untuk mengubah kepemilikan tabel di PostgreSQL: lihat stackoverflow.com/a/13535184
tanius
-6

pastikan pengguna Anda memiliki atribut pada perannya. sebagai contoh:

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

setelah melakukan perintah berikut:

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

itu memperbaiki masalah.

lihat tutorial untuk peran dan hal-hal di sini: https://www.digitalocean.com/community/tutorials/how-to-use-roles-and-manage-grant-permissions-in-postgresql-on-a-vps--2

PuN1sh3r
sumber
18
Tidak! Memberikan peran Superuser kepada pengguna yang disebut "hanya baca" untuk melakukan "pilih" bukanlah perbaikan yang benar.
Anna
@Anna Bukan itu yang terjadi di sini. Utas ini bukan tentang memberikan akses hanya baca. Utas ini tentang memberikan akses kepada pengguna untuk memberikan akses hanya-baca kepada pengguna lain. IMHO, ini benar. Jika pengguna Anda bukan Pengguna Super, Anda tidak dapat membuat pengguna hanya-baca. Kesalahan yang ERROR: permission denied for relation mytable
dialami
-7

Anda harus menjalankan kueri berikutnya:

GRANT ALL ON TABLE mytable TO myuser;

Atau jika kesalahan Anda ada dalam tampilan, maka mungkin tabel tidak memiliki izin, jadi Anda harus menjalankan kueri berikutnya:

GRANT ALL ON TABLE tbm_grupo TO myuser;
ya
sumber
5
Pengguna disebut "hanya baca". Diragukan bahwa memberi pengguna semua izin adalah tujuannya. Dia hanya ingin memilih.
Anna
Ini mengalahkan tujuan penamaan pengguna 'ReadOnly' jika Anda memberikan ALTER DROP DELETEEct. Untuk pengguna itu ...
JayRizzo