PostgreSQL'de salt okunur bir kullanıcı nasıl oluşturulur?


419

PostgreSQL'de sadece belirli bir veritabanından SELECTs yapabilen bir kullanıcı oluşturmak istiyorum. MySQL'de komut şöyle olacaktır:

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

PostgreSQL'de eşdeğer komut veya komut dizisi nedir?

Denedim...

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

Ancak bir veritabanında verebileceğiniz tek şey CREATE, CONNECT, TEMPORARY ve TEMP'dir.

Yanıtlar:


641

Kullanım ver / tek bir tabloya seç

Yalnızca bir veritabanına CONNECT izni verirseniz, kullanıcı bağlanabilir ancak başka ayrıcalıklara sahip değildir. İsim alanlarında (şemalar) USAGE ve tablolarda ve görünümlerde SELECT'i ayrı ayrı şöyle vermeniz gerekir:

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;

Birden çok tablo / görünüm (PostgreSQL 9.0+)

PostgreSQL'in son sürümlerinde, şemadaki tüm tablolar / görünümler / vb. İçin bunları tek tek yazmak yerine tek bir komut kullanarak izin verebilirsiniz:

GRANT SELECT ON ALL TABLES IN SCHEMA public TO xxx;

Bu yalnızca önceden oluşturulmuş tabloları etkiler. Daha güçlü bir şekilde, gelecekte yeni nesnelere varsayılan rollerin otomatik olarak atanmasını sağlayabilirsiniz :

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

Varsayılan olarak, bunun yalnızca bu komutu yayınlayan kullanıcı tarafından oluşturulan nesneleri (tabloları) etkileyeceğini unutmayın: ancak bunu veren kullanıcının üyesi olduğu herhangi bir rol için de ayarlanabilir. Ancak, yeni nesneler oluştururken üyesi olduğunuz tüm roller için varsayılan ayrıcalıklar almazsınız ... bu nedenle hala biraz solgunluk var. Veritabanının sahip olma rolüne sahip olduğu yaklaşımını benimserseniz ve şema değişiklikleri bu sahip olma rolü olarak gerçekleştirilirse, o sahip olma rolüne varsayılan ayrıcalıklar atamalısınız. IMHO bu biraz kafa karıştırıcı ve fonksiyonel bir iş akışı bulmak için denemeniz gerekebilir.

Birden çok tablo / görünüm (9.0'dan önceki PostgreSQL sürümleri)

Uzun, çok tablolu değişikliklerde hatalardan kaçınmak GRANT SELECTiçin, her tablo / görünüm için gerekli olanı oluşturmak üzere aşağıdaki 'otomatik' işlemi kullanmanız önerilir :

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');

Bu, kopyalama-n-yapıştırma aşkı için herkese açık tüm tablolarda, görünümlerde ve dizilerde ilgili GRANT komutlarını GRANT SELECT'e çıktılamalıdır. Doğal olarak, bu sadece önceden oluşturulmuş tablolara uygulanacaktır.


22
PG9 ile ilgili düzenlemenizi yazının en üstüne koymalısınız.
Danilo Bargen

5
Güzel. Ekleyeceğim bir şey de dizilerin bu kullanıcı tarafından okunmasına izin vermeniz gerekebileceğidir; öyleyse: xxx için kamuya açık SCHEMA TÜM SIRALARI SEÇİM;
JJC

26
Bu kullanıcının yeni tablolar oluşturabilmesini önlemek için şunu yapmam gerektiğini unutmayın REVOKE CREATE ON SCHEMA public FROM PUBLIC;. Bu olmadan, "salt okunur" kullanıcı varolan tabloları değiştiremedi, ancak şemada yeni tablolar oluşturabilir ve bu tablolara veri ekleyebilir / kaldırabilir.
Ajedi32

3
@ Ajedi32 Bu kabul edilen cevabın bir parçası olmalı! Teşekkürler
Asfand Qazi

12
Benim gibi yeni başlayanlar için, bence psql mydbbu manipülasyonların çoğunun yapmayacağı bir şekilde konsola başlamanız gerektiğini belirtmek gerekir . Şahsen bunu kendi başıma çözmem çok zaman aldı. Umarım bu birine yardımcı olur.
Anass

41

PostgreSQL 9.0'ın (bugün beta testinde) bunu yapmanın basit bir yolu olacağını unutmayın :

test=> GRANT SELECT ON ALL TABLES IN SCHEMA public TO joeuser;

3
Bunun çalışması için belirli bir veritabanında olmalıydım. Postgresql 9.5.
user1158559

8
Bu yalnızca şemadaki mevcut tablolar için geçerlidir. Yazma kullanıcısı daha sonra tablolar oluşturur veya değiştirirse, salt okunur kullanıcı bunlara erişemez
anneb

32

Bu blogdan alınan referans:

Salt Okunur kullanıcısı oluşturmak için komut dosyası:

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

Bu salt okunur kullanıcıya izin ata:

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;

6
Bu, eksik ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO Read_Only_User; olan tek bir şey dışında çok iyi bir cevaptır: gelecekte aynı DB'de oluşturulan tüm tabloları da okuyacaktır.
Ravbaker

2
Salt okunur bir kullanıcının dizilere erişmesine izin vermek olağandışıdır. Diziyi okumak diziyi günceller ve genellikle yalnızca INSERTs için gereklidir .
jpmc26

GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA schema_name TO Read_Only_User;
Tamlık için

@ jpmc26: bu önerdiğiniz anlamına mı geliyor GRANT ALL ON ALL SEQUENCES IN SCHEMA schema_name TO Read_Only_User?
Fabien Haddadi

@FabienHaddadi Sıradan bir gereksiniminiz yoksa, salt okunur bir kullanıcıya diziler üzerinde izin verme gereği görmüyorum demektir.
jpmc26

24

İşte salt okunur kullanıcılar eklemek için bulduğum en iyi yol (PostgreSQL 9.0 veya daha yenisini kullanarak):

$ 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;

Ardından, ilgili tüm makinelerde (master + read-slave (s) / hot-standby (s) vb.) Oturum açın ve çalıştırın:

$ 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

2
Ben yaklaşımı seviyorum ama aynı zamanda [thedatabase] VERİTABANI ÜZERİNE BAĞLANMAK [kullanıcı veya rol]; ve [kullanıcı veya rol] için kamuya açık SCHEMA'DA HİBE KULLANIM;
Ian Connor

1
Genel şema yine de böyle bir kullanıcının tablo oluşturmasına izin verir. Ayrıca, yeni tablolar ve diziler de kapsanmaz. Ne yazık ki, bunların hepsi bundan biraz daha karmaşık. : - / Biraz daha doğruladıktan sonra ne yaptığımı göndereceğim.
JJC

Yukarıdaki komut dosyanızda rolü iki kez oluşturmaya çalışıyorsunuz. Oturum açma rolünü etkinleştirirken ve şifreyi ayarlarken "ALTER ROLE ..." kullanmayı düşündüğünüzden şüpheleniyorum
Bogdan

Kullanıcıya zaten sahipseniz, salt okunur rolü ve hibe seçme izinlerini oluşturduktan sonra kullanıcıya yeni bir rol verir: GRANT salt okunur TO <USER>
gonz

18

Varsayılan olarak yeni kullanıcıların tablo oluşturma izni olur. Salt okunur bir kullanıcı oluşturmayı planlıyorsanız, bu muhtemelen istediğiniz şey değildir.

PostgreSQL 9.0+ ile gerçek bir salt okunur kullanıcı oluşturmak için aşağıdaki adımları çalıştırın:

# 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;

Salt okunur kullanıcınızın tabloları listeleme izni yoksa (yani \dsonuç döndürmez), bunun nedeni büyük olasılıkla USAGEşema için izinleriniz olmamasıdır . USAGE, kullanıcıların kendilerine atanan izinleri gerçekten kullanmalarına izin veren bir izindir. Bunun amacı ne? Emin değilim. Düzeltmek:

# 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;

8

Bunun için uygun bir senaryo oluşturdum; pg_grant_read_to_db.sh . Bu komut dosyası, bir veritabanı şemasındaki tüm tablolarda, görünümlerde ve dizilerde belirtilen bir role salt okunur ayrıcalıklar verir ve bunları varsayılan olarak ayarlar.


4

Eğer şeyler vermeden önce veritabanına bağlanmayı hatırlarsanız, tüm iyi olası tüm çözümler, yalak okuyorum;) Yine de diğer tüm çözümlere teşekkürler !!!

user@server:~$ sudo su - postgres

psql kullanıcısı oluşturun:

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

psql cli'yi başlatın ve oluşturulan kullanıcı için bir şifre belirleyin:

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

hedef veritabanına bağlan:

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".

gerekli tüm ayrıcalıkları verin:

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

db public shema hedefleri için varsayılan ayrıcalıkları değiştirin:

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

3

Veritabanınız genel şemadaysa, kolaydır (bu zaten oluşturduğunuzu varsayar 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

Veritabanınız kullanıyorsa customschema, yukarıdakileri yürütün ancak bir komut daha ekleyin:

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

1

Bunu yapmanın kolay olmayan yolu, veritabanının her bir tablosunda select seçmektir:

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

Veritabanı meta verilerinden hibe ifadelerinizi oluşturarak bunu otomatikleştirebilirsiniz.


1
CREATE USER username SUPERUSER  password 'userpass';
ALTER USER username set default_transaction_read_only = on;

0

Despesz ' linkine yanıt olarak gönderilen bir linkten alınmıştır .

Postgres 9.x, istenenleri yapma yeteneğine sahip gibi görünüyor. Aşağıdaki Veritabanı Nesneleri için Verme paragrafına bakın:

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

Nerede diyor ki: "Bir veya daha fazla şemada aynı türdeki tüm nesnelere ayrıcalık verme seçeneği de vardır. Bu işlevsellik şu anda yalnızca tablolar, sıralar ve işlevler için desteklenmektedir (ancak TÜM TABLOLAR'ın görünümleri içerdiğini unutmayın ve yabancı masalar). "

Bu sayfada ayrıca ROLE'lerin ve "TÜM AYRICALIKLAR" adı verilen bir PRIVILEGE kullanımı tartışılmaktadır.

Ayrıca, GRANT işlevlerinin SQL standartlarıyla nasıl karşılaştırıldığı hakkında bilgi de mevcuttur.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.