Bagaimana Anda membuat pengguna read-only di PostgreSQL?

420

Saya ingin membuat pengguna di PostgreSQL yang hanya dapat melakukan SELECT dari database tertentu. Dalam MySQL perintahnya adalah:

GRANT SELECT ON mydb.* TO 'xxx'@'%' IDENTIFIED BY 'yyy';

Apa perintah yang setara atau serangkaian perintah di PostgreSQL?

Saya mencoba...

postgres=# CREATE ROLE xxx LOGIN PASSWORD 'yyy';
postgres=# GRANT SELECT ON DATABASE mydb TO xxx;

Tetapi tampaknya satu-satunya hal yang dapat Anda berikan pada basis data adalah CREATE, CONNECT, TEMPORARY, dan TEMP.

Ethan
sumber

Jawaban:

641

Berikan penggunaan / pilih ke satu tabel

Jika Anda hanya memberikan CONNECT ke database, pengguna dapat terhubung tetapi tidak memiliki hak istimewa lainnya. Anda harus memberikan PENGGUNAAN pada ruang nama (skema) dan PILIH pada tabel dan tampilan secara individual seperti:

GRANT CONNECT ON DATABASE mydb TO xxx;
-- This assumes you're actually connected to mydb..
GRANT USAGE ON SCHEMA public TO xxx;
GRANT SELECT ON mytable TO xxx;

Beberapa tabel / tampilan (PostgreSQL 9.0+)

Dalam versi terbaru PostgreSQL, Anda dapat memberikan izin pada semua tabel / tampilan / dll dalam skema menggunakan perintah tunggal daripada harus mengetiknya satu per satu:

GRANT SELECT ON ALL TABLES IN SCHEMA public TO xxx;

Ini hanya memengaruhi tabel yang sudah dibuat. Lebih kuat, Anda dapat secara otomatis memiliki peran default yang ditetapkan untuk objek baru di masa depan:

ALTER DEFAULT PRIVILEGES IN SCHEMA public
   GRANT SELECT ON TABLES TO xxx;

Perhatikan bahwa secara default ini hanya akan mempengaruhi objek (tabel) yang dibuat oleh pengguna yang mengeluarkan perintah ini: meskipun juga dapat ditetapkan pada peran apa pun yang menjadi anggota pengguna yang mengeluarkan. Namun, Anda tidak mengambil hak default untuk semua peran yang menjadi anggota Anda saat membuat objek baru ... jadi masih ada beberapa hal yang perlu dilakukan. Jika Anda mengadopsi pendekatan yang memiliki peran sebagai basis data, dan perubahan skema dilakukan sebagai peran tersebut, maka Anda harus menetapkan hak default untuk peran tersebut. IMHO ini semua agak membingungkan dan Anda mungkin perlu bereksperimen untuk menghasilkan alur kerja fungsional.

Beberapa tabel / tampilan (versi PostgreSQL sebelum 9.0)

Untuk menghindari kesalahan dalam perubahan multi-tabel yang panjang, disarankan untuk menggunakan proses 'otomatis' berikut untuk menghasilkan yang diperlukan GRANT SELECTuntuk setiap tabel / tampilan:

SELECT 'GRANT SELECT ON ' || relname || ' TO xxx;'
FROM pg_class JOIN pg_namespace ON pg_namespace.oid = pg_class.relnamespace
WHERE nspname = 'public' AND relkind IN ('r', 'v', 'S');

Ini harus menampilkan perintah GRANT yang relevan ke GRANT SELECT pada semua tabel, tampilan, dan urutan di depan umum, untuk cinta salin-tempel. Secara alami, ini hanya akan diterapkan ke tabel yang sudah dibuat.

araqnid
sumber
22
Anda harus meletakkan hasil edit Anda tentang PG9 di bagian atas pos.
Danilo Bargen
5
Bagus. Satu hal yang saya tambahkan adalah bahwa Anda mungkin juga perlu membolehkan urutan dibaca oleh pengguna ini; jadi: GRANT PILIH PADA SEMUA SEQUENCES DI SCHEMA public TO xxx;
JJC
26
Perhatikan bahwa untuk mencegah pengguna ini membuat tabel baru, saya harus melakukannya REVOKE CREATE ON SCHEMA public FROM PUBLIC;. Tanpa itu, pengguna "read only" tidak bisa memodifikasi tabel yang ada, tetapi bisa membuat tabel baru dalam skema dan menambah / menghapus data dari tabel tersebut.
Ajedi32
3
@ Ajedi32 Ini harus menjadi bagian dari jawaban yang diterima! Terima kasih
Asfand Qazi
12
Untuk pemula seperti saya, saya pikir itu layak disebutkan bahwa Anda harus memulai konsol menggunakan psql mydbsebaliknya sebagian besar manipulasi ini tidak akan berhasil. Secara pribadi saya membutuhkan banyak waktu untuk mengetahuinya sendiri. Semoga ini bisa membantu seseorang.
Anass
41

Perhatikan bahwa PostgreSQL 9.0 (hari ini dalam pengujian beta) akan memiliki cara sederhana untuk melakukan itu :

test=> GRANT SELECT ON ALL TABLES IN SCHEMA public TO joeuser;
bortzmeyer
sumber
3
Saya harus berada di database khusus agar ini berfungsi. Postgresql 9.5.
user1158559
8
Ini hanya berfungsi untuk tabel yang ada di skema. Jika pengguna menulis nanti membuat atau mengganti tabel, pengguna hanya baca tidak akan memiliki akses ke mereka
anneb
33

Referensi diambil dari blog ini:

Skrip untuk Membuat Pengguna Hanya-Baca:

CREATE ROLE Read_Only_User WITH LOGIN PASSWORD 'Test1234' 
NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE NOREPLICATION VALID UNTIL 'infinity';

Tetapkan izin untuk pengguna hanya baca ini:

GRANT CONNECT ON DATABASE YourDatabaseName TO Read_Only_User;
GRANT USAGE ON SCHEMA public TO Read_Only_User;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO Read_Only_User;
GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO Read_Only_User;

Tetapkan izin untuk membaca semua tabel baru yang dibuat di masa mendatang

ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO Read_Only_User;
Landasan
sumber
6
Ini adalah jawaban yang sangat bagus kecuali satu hal yang hilang: ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO Read_Only_User; yang juga memungkinkan untuk membaca semua tabel yang dibuat dalam DB yang sama di masa depan.
Ravbaker
2
Merupakan hal yang tidak biasa untuk mengizinkan akses pengguna hanya baca ke sekuens. Membaca urutan memperbaruinya, dan biasanya hanya diperlukan untuk INSERTs.
jpmc26
Untuk kelengkapan, mungkin tambahkan:GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA schema_name TO Read_Only_User;
Fabien Haddadi
@ jpmc26: apakah itu berarti bahwa Anda rekomendasikan: GRANT ALL ON ALL SEQUENCES IN SCHEMA schema_name TO Read_Only_User?
Fabien Haddadi
@FabienHaddadi Ini berarti bahwa kecuali Anda memiliki beberapa dari persyaratan biasa, saya tidak melihat kebutuhan untuk memberikan izin pada urutan ke pengguna hanya baca.
jpmc26
24

Inilah cara terbaik yang saya temukan untuk menambahkan pengguna hanya baca (menggunakan PostgreSQL 9.0 atau yang lebih baru):

$ sudo -upostgres psql postgres
postgres=# CREATE ROLE readonly WITH LOGIN ENCRYPTED PASSWORD '<USE_A_NICE_STRONG_PASSWORD_PLEASE';
postgres=# GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonly;

Kemudian masuk ke semua mesin terkait (master + read-slave / hot-standby, dll.) Dan jalankan:

$ echo "hostssl <PUT_DBNAME_HERE> <PUT_READONLY_USERNAME_HERE> 0.0.0.0/0 md5" | sudo tee -a /etc/postgresql/9.2/main/pg_hba.conf
$ sudo service postgresql reload
Jay Taylor
sumber
2
Saya suka pendekatannya tetapi saya juga perlu MENGHARGAI HUBUNGAN PADA DATABASE [database] KE [pengguna atau peran]; dan PENGGUNAAN GRANT ON SCHEMA public TO [theuser or role];
Ian Connor
1
Skema publik masih memungkinkan pengguna seperti itu untuk membuat tabel. Juga, tabel baru tidak tercakup, juga urutan. Sayangnya, ini semua sedikit lebih rumit dari ini. : - / Saya akan memposting apa yang akhirnya saya lakukan setelah saya memvalidasinya lagi.
JJC
Dalam skrip di atas, Anda mencoba membuat peran dua kali. Saya menduga Anda bermaksud menggunakan "ALTER ROLE ..." saat mengaktifkan peran untuk masuk dan mengatur kata sandi
Bogdan
Jika Anda sudah memiliki pengguna, setelah membuat peran hanya baca dan berikan izin pilih berikan peran baru kepada pengguna: GRANT baca saja KE <USER>
gonz
18

Secara default, pengguna baru akan memiliki izin untuk membuat tabel. Jika Anda berencana membuat pengguna hanya-baca, ini mungkin bukan yang Anda inginkan.

Untuk membuat pengguna hanya baca yang benar dengan PostgreSQL 9.0+, jalankan langkah-langkah berikut:

# This will prevent default users from creating tables
REVOKE CREATE ON SCHEMA public FROM public;

# If you want to grant a write user permission to create tables
# note that superusers will always be able to create tables anyway
GRANT CREATE ON SCHEMA public to writeuser;

# Now create the read-only user
CREATE ROLE readonlyuser WITH LOGIN ENCRYPTED PASSWORD 'strongpassword';
GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonlyuser;

Jika pengguna hanya-baca Anda tidak memiliki izin untuk mendaftar tabel (yaitu \dtidak mengembalikan hasil), itu mungkin karena Anda tidak memiliki USAGEizin untuk skema. USAGEadalah izin yang memungkinkan pengguna untuk benar-benar menggunakan izin yang telah mereka tetapkan. Apa gunanya ini? Saya tidak yakin. Memperbaiki:

# You can either grant USAGE to everyone
GRANT USAGE ON SCHEMA public TO public;

# Or grant it just to your read only user
GRANT USAGE ON SCHEMA public TO readonlyuser;
Adrian Macneil
sumber
8

Saya telah membuat skrip yang mudah untuk itu; pg_grant_read_to_db.sh . Skrip ini memberikan hak istimewa hanya-baca untuk peran tertentu pada semua tabel, tampilan, dan urutan dalam skema database dan menetapkannya sebagai default.

Jakub Jirutka
sumber
4

Saya membaca semua solusi yang mungkin, yang semuanya baik-baik saja, jika Anda ingat untuk terhubung ke database sebelum Anda memberikan hal-hal;) Bagaimanapun juga terima kasih untuk semua solusi lain !!!

user@server:~$ sudo su - postgres

buat pengguna psql:

postgres@server:~$ createuser --interactive 
Enter name of role to add: readonly
Shall the new role be a superuser? (y/n) n
Shall the new role be allowed to create databases? (y/n) n
Shall the new role be allowed to create more new roles? (y/n) n

mulai psql cli dan atur kata sandi untuk pengguna yang dibuat:

postgres@server:~$ psql
psql (10.6 (Ubuntu 10.6-0ubuntu0.18.04.1), server 9.5.14)
Type "help" for help.

postgres=# alter user readonly with password 'readonly';
ALTER ROLE

terhubung ke database target:

postgres=# \c target_database 
psql (10.6 (Ubuntu 10.6-0ubuntu0.18.04.1), server 9.5.14)
You are now connected to database "target_database" as user "postgres".

berikan semua hak istimewa yang dibutuhkan:

target_database=# GRANT CONNECT ON DATABASE target_database TO readonly;
GRANT

target_database=# GRANT USAGE ON SCHEMA public TO readonly ;
GRANT

target_database=# GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonly ;
GRANT

ubah hak standar untuk target db shema publik:

target_database=# ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO readonly;
ALTER DEFAULT PRIVILEGES
terima kasih
sumber
3

Jika database Anda dalam skema publik, itu mudah (ini mengasumsikan Anda sudah membuat readonlyuser)

db=> GRANT SELECT ON ALL TABLES IN SCHEMA public to readonlyuser;
GRANT
db=> GRANT CONNECT ON DATABASE mydatabase to readonlyuser;
GRANT
db=> GRANT SELECT ON ALL SEQUENCES IN SCHEMA public to readonlyuser;
GRANT

Jika basis data Anda digunakan customschema, jalankan perintah di atas tetapi tambahkan satu perintah lagi:

db=> ALTER USER readonlyuser SET search_path=customschema, public;
ALTER ROLE
josephmisiti
sumber
1

Cara tidak langsung untuk melakukannya adalah dengan memberikan pilih pada setiap tabel database:

postgres=# grant select on db_name.table_name to read_only_user;

Anda dapat mengotomatiskannya dengan membuat pernyataan hibah dari metadata database.

Pablo Santa Cruz
sumber
1
CREATE USER username SUPERUSER  password 'userpass';
ALTER USER username set default_transaction_read_only = on;
Viktor Viktor
sumber
0

Diambil dari tautan yang diposting sebagai tanggapan terhadap tautan despesz ' .

Postgres 9.x tampaknya memiliki kemampuan untuk melakukan apa yang diminta. Lihat paragraf Obyek Hibah Basis Data:

http://www.postgresql.org/docs/current/interactive/sql-grant.html

Di mana dikatakan: "Ada juga opsi untuk memberikan hak istimewa pada semua objek dengan tipe yang sama dalam satu atau lebih skema. Fungsi ini saat ini hanya didukung untuk tabel, sekuens, dan fungsi (tetapi perhatikan bahwa SEMUA TABEL dianggap termasuk tampilan) dan tabel asing). "

Halaman ini juga membahas penggunaan ROLEs dan PRIVILEGE yang disebut "ALL PRIVILEGES".

Juga hadir informasi tentang bagaimana fungsionalitas GRANT dibandingkan dengan standar SQL.

kbulgrien
sumber