Wie erstellen Sie einen schreibgeschützten Benutzer in PostgreSQL?


418

Ich möchte einen Benutzer in PostgreSQL erstellen, der nur SELECTs aus einer bestimmten Datenbank ausführen kann. In MySQL wäre der Befehl:

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

Was ist der entsprechende Befehl oder eine Reihe von Befehlen in PostgreSQL?

Ich habe es versucht...

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

Es scheint jedoch, dass die einzigen Dinge, die Sie für eine Datenbank gewähren können, CREATE, CONNECT, TEMPORARY und TEMP sind.

Antworten:


640

Gewähren Sie Verwendung / Auswahl für eine einzelne Tabelle

Wenn Sie einer Datenbank nur CONNECT gewähren, kann der Benutzer eine Verbindung herstellen, hat jedoch keine anderen Berechtigungen. Sie müssen USAGE für Namespaces (Schemas) und SELECT für Tabellen und Ansichten wie folgt gewähren:

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;

Mehrere Tabellen / Ansichten (PostgreSQL 9.0+)

In den neuesten Versionen von PostgreSQL können Sie Berechtigungen für alle Tabellen / Ansichten / usw. im Schema mit einem einzigen Befehl erteilen, anstatt sie einzeln eingeben zu müssen:

GRANT SELECT ON ALL TABLES IN SCHEMA public TO xxx;

Dies betrifft nur Tabellen, die bereits erstellt wurden. Leistungsstärker können Sie künftig automatisch Standardrollen neuen Objekten zuweisen :

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

Beachten Sie, dass dies standardmäßig nur Objekte (Tabellen) betrifft, die von dem Benutzer erstellt wurden, der diesen Befehl ausgegeben hat. Er kann jedoch auch für jede Rolle festgelegt werden, in der der ausstellende Benutzer Mitglied ist. Sie erhalten jedoch nicht für alle Rollen, denen Sie angehören, Standardberechtigungen, wenn Sie neue Objekte erstellen. Es gibt also immer noch einige Probleme. Wenn Sie den Ansatz wählen, dass eine Datenbank eine Eigentümerrolle hat und Schemaänderungen als diese Eigentümerrolle ausgeführt werden, sollten Sie dieser Eigentümerrolle Standardberechtigungen zuweisen. IMHO ist das alles etwas verwirrend und Sie müssen möglicherweise experimentieren, um einen funktionierenden Workflow zu entwickeln.

Mehrere Tabellen / Ansichten (PostgreSQL-Versionen vor 9.0)

Um Fehler bei langwierigen Änderungen mit mehreren Tabellen zu vermeiden, wird empfohlen, den folgenden "automatischen" Prozess zu verwenden, um die GRANT SELECTfür jede Tabelle / Ansicht erforderlichen Daten zu generieren :

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

Dies sollte die relevanten GRANT-Befehle für alle Tabellen, Ansichten und Sequenzen in der Öffentlichkeit an GRANT SELECT ausgeben, um die Liebe zum Kopieren und Einfügen zu gewährleisten. Dies gilt natürlich nur für bereits erstellte Tabellen.


22
Sie sollten Ihre Bearbeitung in Bezug auf PG9 oben im Beitrag einfügen.
Danilo Bargen

5
Nett. Eine Sache, die ich hinzufügen möchte, ist, dass Sie möglicherweise auch zulassen müssen, dass Sequenzen von diesem Benutzer gelesen werden. also: GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO xxx;
JJC

26
Beachten Sie, dass ich dies tun musste, um zu verhindern, dass dieser Benutzer neue Tabellen erstellen kann REVOKE CREATE ON SCHEMA public FROM PUBLIC;. Ohne dies könnte der "schreibgeschützte" Benutzer vorhandene Tabellen nicht ändern, sondern neue Tabellen im Schema erstellen und Daten zu diesen Tabellen hinzufügen / daraus entfernen.
Ajedi32

3
@ Ajedi32 Dies sollte Teil der akzeptierten Antwort sein! Danke
Asfand Qazi

12
Für Neulinge wie mich ist es erwähnenswert, dass Sie die Konsole mit psql mydbanderen Methoden starten sollten, da dies sonst nicht der Fall wäre. Ich persönlich habe viel Zeit gebraucht, um es selbst herauszufinden. Hoffe das hilft jemandem.
Anass

41

Beachten Sie, dass PostgreSQL 9.0 (heute im Beta-Test) eine einfache Möglichkeit bietet, dies zu tun :

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

3
Ich musste in der spezifischen Datenbank sein, damit dies funktioniert. Postgresql 9.5.
user1158559

8
Dies funktioniert nur für vorhandene Tabellen im Schema. Wenn der Schreibbenutzer später Tabellen erstellt oder ersetzt, hat der schreibgeschützte Benutzer keinen Zugriff darauf
anneb

32

Referenz aus diesem Blog:

Skript zum Erstellen eines schreibgeschützten Benutzers:

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

Weisen Sie diesem schreibgeschützten Benutzer die Berechtigung zu:

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
Dies ist eine sehr gute Antwort, mit der Ausnahme, dass eines fehlt: Damit können in ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO Read_Only_User; Zukunft auch alle in derselben Datenbank erstellten Tabellen gelesen werden.
Ravbaker

2
Es ist ungewöhnlich, einem schreibgeschützten Benutzer Zugriff auf die Sequenzen zu gewähren. Durch das Lesen der Sequenz wird sie aktualisiert und normalerweise nur für INSERTs benötigt .
jpmc26

Der Vollständigkeit halber fügen Sie möglicherweise hinzu:GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA schema_name TO Read_Only_User;
Fabien Haddadi

@ jpmc26: heißt das, dass du empfehlst : GRANT ALL ON ALL SEQUENCES IN SCHEMA schema_name TO Read_Only_User?
Fabien Haddadi

@FabienHaddadi Es bedeutet, dass ich, sofern Sie keine außergewöhnlichen Anforderungen haben, keine Notwendigkeit sehe, einem schreibgeschützten Benutzer Berechtigungen für Sequenzen zu erteilen.
jpmc26

24

Hier ist der beste Weg, schreibgeschützte Benutzer hinzuzufügen (mit PostgreSQL 9.0 oder neuer):

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

Melden Sie sich dann bei allen zugehörigen Computern an (Master + Read-Slave (s) / Hot-Standby (s) usw.) und führen Sie Folgendes aus:

$ 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
Ich mag den Ansatz, aber ich musste auch CONNECT ON DATABASE [thedatabase] TO [theuser or role] gewähren; und GEWÄHRUNG DER NUTZUNG DES SCHEMAS öffentlich AN [Benutzer oder Rolle];
Ian Connor

1
Das öffentliche Schema ermöglicht es einem solchen Benutzer weiterhin, Tabellen zu erstellen. Außerdem werden weder neue Tabellen noch Sequenzen behandelt. Leider ist das alles etwas komplizierter. : - / Ich werde posten, was ich getan habe, sobald ich es noch einmal validiert habe.
JJC

In Ihrem obigen Skript versuchen Sie, die Rolle zweimal zu erstellen. Ich vermute, dass Sie beabsichtigten, "ALTER ROLE ..." zu verwenden, wenn Sie die Rolle für die Anmeldung aktivieren und das Passwort
Bogdan

Wenn Sie den Benutzer bereits haben, gewähren Sie dem Benutzer nach dem Erstellen der schreibgeschützten Rolle und dem Gewähren ausgewählter Dauerwellen die neue Rolle: GRANT schreibgeschützt an <BENUTZER>
gonz

18

Standardmäßig haben neue Benutzer die Berechtigung, Tabellen zu erstellen. Wenn Sie vorhaben, einen schreibgeschützten Benutzer zu erstellen, ist dies wahrscheinlich nicht das, was Sie möchten.

Führen Sie die folgenden Schritte aus, um mit PostgreSQL 9.0+ einen echten schreibgeschützten Benutzer zu erstellen:

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

Wenn Ihr schreibgeschützter Benutzer keine Berechtigung zum Auflisten von Tabellen hat (dh \dkeine Ergebnisse zurückgibt), liegt dies wahrscheinlich daran, dass Sie keine USAGEBerechtigungen für das Schema haben. USAGEist eine Berechtigung, mit der Benutzer die ihnen zugewiesenen Berechtigungen tatsächlich verwenden können. Was ist der Sinn davon? Ich bin mir nicht sicher. Reparieren:

# 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

Ich habe dafür ein praktisches Skript erstellt. pg_grant_read_to_db.sh . Dieses Skript gewährt einer bestimmten Rolle schreibgeschützte Berechtigungen für alle Tabellen, Ansichten und Sequenzen in einem Datenbankschema und legt diese als Standard fest.


4

Ich habe alle möglichen Lösungen durchgelesen, die alle in Ordnung sind, wenn Sie daran denken, eine Verbindung zur Datenbank herzustellen, bevor Sie die Dinge gewähren;) Trotzdem danke an alle anderen Lösungen !!!

user@server:~$ sudo su - postgres

Erstellen Sie einen psql-Benutzer:

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

Starten Sie psql cli und legen Sie ein Passwort für den erstellten Benutzer fest:

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

Verbindung zur Zieldatenbank herstellen:

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

Gewähren Sie alle erforderlichen Berechtigungen:

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

Standardberechtigungen für Ziele ändern db public shema:

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

3

Wenn sich Ihre Datenbank im öffentlichen Schema befindet, ist dies einfach (dies setzt voraus, dass Sie das bereits erstellt haben 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

Wenn Ihre Datenbank verwendet wird customschema, führen Sie den obigen Vorgang aus, fügen Sie jedoch einen weiteren Befehl hinzu:

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

1

Die nicht einfache Möglichkeit wäre, select für jede Tabelle der Datenbank zu gewähren:

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

Sie können dies automatisieren, indem Sie Ihre Grant-Anweisungen aus den Datenbank-Metadaten generieren.


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

0

Entnommen aus einem Link, der als Antwort auf den Link von despesz gepostet wurde .

Postgres 9.x scheint die Fähigkeit zu haben, das zu tun, was angefordert wird. Siehe den Abschnitt Grant On Database Objects von:

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

Wo es heißt: "Es gibt auch eine Option, Berechtigungen für alle Objekte desselben Typs innerhalb eines oder mehrerer Schemas zu erteilen. Diese Funktionalität wird derzeit nur für Tabellen, Sequenzen und Funktionen unterstützt (beachten Sie jedoch, dass ALLE TABELLEN Ansichten enthalten und fremde Tabellen). "

Auf dieser Seite wird auch die Verwendung von ROLLEN und eines PRIVILEGES mit dem Namen "ALLE PRIVILEGIEN" erläutert.

Ebenfalls vorhanden sind Informationen darüber, wie GRANT-Funktionen mit SQL-Standards verglichen werden.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.