Jak utworzyć użytkownika tylko do odczytu w PostgreSQL?

Chciałbym utworzyć użytkownika w PostgreSQL, który może wykonywać tylko selekcje z konkretnej bazy danych. W MySQL Komenda brzmiałaby:

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

Jaka jest równoważna Komenda lub seria komend w PostgreSQL?

Próbowałem...
postgres=# CREATE ROLE xxx LOGIN PASSWORD 'yyy';
postgres=# GRANT SELECT ON DATABASE mydb TO xxx;

Ale wygląda na to, że jedyne rzeczy, które możesz przyznać w bazie danych, to CREATE, CONNECT, TEMPORARY i TEMP.

 336
Author: Peter Mortensen, 2009-04-17

9 answers

Wykorzystanie dotacji / select to a single table

Jeśli przyznasz CONNECT tylko bazie danych, użytkownik może się połączyć, ale nie ma innych uprawnień. Musisz przyznać użycie na przestrzeniach nazw (schematach) i wybrać na tabelach i widokach indywidualnie tak:

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;

Wiele tabel/widoków (PostgreSQL 9.0+)

W najnowszych wersjach PostgreSQL, możesz nadać uprawnienia do wszystkich tabel/widoków / etc w schemacie używając jednego polecenia, a nie wpisując je pojedynczo jeden:

GRANT SELECT ON ALL TABLES IN SCHEMA public TO xxx;

Dotyczy to tylko tych tabel, które zostały już utworzone. Co więcej, możesz automatycznie przypisać domyślne role nowym obiektom w przyszłości:

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

Zauważ, że domyślnie dotyczy to tylko obiektów (tabel) utworzonych przez użytkownika, który wydał to polecenie: chociaż może być również ustawione na dowolnej roli, której użytkownik jest członkiem. Jednak podczas tworzenia nowych obiektów nie uzyskuje się domyślnych uprawnień dla wszystkich ról, których jesteś członkiem... więc wciąż jest jakiś faffer. Jeśli przyjmiesz podejście, że baza danych ma rolę właściciela, a zmiany schematu są wykonywane jako ta rola właściciela, powinieneś przypisać domyślne uprawnienia do tej roli właściciela. IMHO to wszystko jest trochę mylące i być może będziesz musiał eksperymentować, aby wymyślić funkcjonalny przepływ pracy.

Wiele tabel/widoków (wersje PostgreSQL przed 9.0)

Aby uniknąć błędów w długich, wielostolikowych zmianach, zaleca się użycie następującego "automatycznego" proces generowania wymaganego GRANT SELECT do każdej tabeli/widoku:

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

To powinno wypisać odpowiednie polecenia GRANT, aby przyznać SELECT we wszystkich tabelach, widokach i sekwencjach publicznie, dla miłości copy-n-paste. Oczywiście będzie to stosowane tylko do tabel, które zostały już utworzone.

 513
Author: araqnid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-24 19:58:22

Zauważ, że PostgreSQL 9.0 (dzisiaj w beta testach) będzie miał prosty sposób na to :

test=> GRANT SELECT ON ALL TABLES IN SCHEMA public TO joeuser;
GRANT
 34
Author: bortzmeyer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-19 21:21:01

Oto najlepszy sposób, jaki znalazłem, aby dodać użytkowników tylko do odczytu (używając PostgreSQL 9.0 lub nowszego):

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

Następnie zaloguj się do wszystkich powiązanych maszyn(master + read-slave (s) / hot-standby (s), itp..) I run:

$ 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
 22
Author: Jay Taylor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-20 23:00:39

Odniesienie zaczerpnięte z tego bloga:

Skrypt do utworzenia użytkownika Tylko do odczytu:

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

Przypisanie uprawnień użytkownikowi tylko do odczytu:

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;
 14
Author: Anvesh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-04 19:51:34

Domyślnie Nowi użytkownicy będą mieli uprawnienia do tworzenia tabel. Jeśli planujesz utworzyć użytkownika tylko do odczytu, prawdopodobnie nie jest to to, czego chcesz.

Aby utworzyć prawdziwego użytkownika tylko do odczytu z PostgreSQL 9.0+, wykonaj następujące kroki:

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

Jeśli twój Użytkownik Tylko do odczytu nie ma uprawnień do wyświetlania tabel (tzn. \d nie zwraca żadnych wyników), prawdopodobnie dlatego, że nie masz uprawnień USAGE dla schematu. USAGE jest uprawnieniem, które pozwala użytkownikom na rzeczywiste korzystanie z uprawnień zostali przydzieleni. Jaki to ma sens? Nie jestem pewien. Do naprawy:

# 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;
 9
Author: Adrian Macneil,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-20 23:03:05

Stworzyłem do tego wygodny skrypt; pg_grant_read_to_db.sh . skrypt nadaje uprawnienia tylko do odczytu określonej roli we wszystkich tabelach, widokach i sekwencjach w schemacie bazy danych i ustawia je jako domyślne.

 8
Author: Jakub Jirutka,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-14 20:27:36

Jeśli twoja baza danych znajduje się w publicznym schemacie, jest to łatwe (zakłada się, że już utworzyłeś 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

Jeśli twoja baza danych używa customschema, wykonaj powyższe polecenie, ale dodaj jeszcze jedną komendę:

db=> ALTER USER readonlyuser SET search_path=customschema, public;
ALTER ROLE
 2
Author: josephmisiti,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-28 17:07:55

Niełatwym sposobem zrobienia tego byłoby przyznanie select na każdej tabeli bazy danych:

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

Można to zautomatyzować, generując deklaracje dotacji z metadanych bazy danych.

 1
Author: Pablo Santa Cruz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-17 12:35:08

Wzięte z linku zamieszczonego w odpowiedzi na link despesz'.

Postgres 9.x wydaje się mieć możliwość wykonania tego, co jest wymagane. Zobacz akapit Grant On database Objects:

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

Gdzie jest napisane: "istnieje również opcja nadawania uprawnień wszystkim obiektom tego samego typu w ramach jednego lub kilku schematów. Ta funkcjonalność jest obecnie obsługiwana tylko dla tabel, sekwencji i funkcje (ale należy pamiętać, że wszystkie tabele są uważane za zawierające widoki i tabele obce)."

Ta strona omawia również użycie ról i przywileju o nazwie "wszystkie przywileje".

Obecna jest również informacja o tym, jak funkcjonalności GRANT porównują się do standardów SQL.

 0
Author: kbulgrien,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-27 16:22:09