J'aimerais créer un utilisateur dans PostgreSQL qui ne peut faire que des sélections à partir d'une base de données particulière. Dans MySQL, la commande serait:
GRANT SELECT ON mydb.* TO 'xxx'@'%' IDENTIFIED BY 'yyy';
Quelle est la commande ou la série de commandes équivalente dans PostgreSQL?
J'ai essayé...
postgres=# CREATE ROLE xxx LOGIN PASSWORD 'yyy';
postgres=# GRANT SELECT ON DATABASE mydb TO xxx;
Mais il semble que les seules choses que vous puissiez accorder sur une base de données soient CREATE, CONNECT, TEMPORARY et TEMP.
Si vous n'accordez que CONNECT à une base de données, l'utilisateur peut se connecter mais ne dispose d'aucun autre privilège. Vous devez accorder USAGE sur les espaces de noms (schémas) et SELECT sur les tables et les vues individuellement, comme ceci:
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;
Dans les dernières versions de PostgreSQL, vous pouvez accorder des autorisations sur toutes les tables/vues/etc. du schéma à l'aide d'une seule commande, sans avoir à les saisir une par une:
GRANT SELECT ON ALL TABLES IN SCHEMA public TO xxx;
Ceci n'affecte que les tables déjà créées. Plus puissamment, vous pouvez automatiquement attribuer default des rôles à de nouveaux objets à l'avenir:
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT ON TABLES TO xxx;
Notez que, par défaut, cela n'affectera que les objets (tables) créés par l'utilisateur qui a émis cette commande: bien qu'il puisse également être défini sur n'importe quel rôle dont l'utilisateur émetteur est membre. Cependant, vous ne récupérez pas les privilèges par défaut pour tous les rôles dont vous êtes membre lors de la création de nouveaux objets ... il y a donc encore des problèmes. Si vous adoptez l'approche selon laquelle une base de données possède un rôle propriétaire et que les modifications de schéma sont effectuées en tant que rôle propriétaire, vous devez attribuer des privilèges par défaut à ce rôle propriétaire. IMHO c'est tout un peu déroutant et vous devrez peut-être expérimenter pour arriver à un flux de travail fonctionnel.
Pour éviter les erreurs lors de modifications longues et multi-tables, il est recommandé d'utiliser le processus "automatique" suivant pour générer le GRANT SELECT
requis dans chaque table/vue:
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');
Cela devrait générer les commandes GRANT appropriées vers GRANT SELECT sur toutes les tables, vues et séquences en public, pour l'amour du copier-coller. Naturellement, cela ne s'appliquera qu'aux tables déjà créées.
Notez que PostgreSQL 9.0 (actuellement en test bêta) aura un moyen simple de le faire
test=> GRANT SELECT ON ALL TABLES IN SCHEMA public TO joeuser;
GRANT
Voici le meilleur moyen que j'ai trouvé d'ajouter des utilisateurs en lecture seule (à l'aide de PostgreSQL 9.0 ou plus récent):
$ 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;
Puis connectez-vous à toutes les machines associées (maître + esclave (s) lecture/hot-standby (s), etc.) et exécutez:
$ 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
Référence extraite de ce blog:
Script pour créer un utilisateur en lecture seule:
CREATE ROLE Read_Only_User WITH LOGIN PASSWORD 'Test1234'
NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE NOREPLICATION VALID UNTIL 'infinity';
Attribuer la permission à cet utilisateur en lecture seule:
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;
Par défaut, les nouveaux utilisateurs seront autorisés à créer des tables. Si vous envisagez de créer un utilisateur en lecture seule, ce n'est probablement pas ce que vous voulez.
Pour créer un véritable utilisateur en lecture seule avec PostgreSQL 9.0+, procédez comme suit:
# 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;
Si votre utilisateur en lecture seule n'a pas l'autorisation de répertorier les tables (c'est-à-dire que \d
ne renvoie aucun résultat), c'est probablement parce que vous n'avez pas d'autorisation USAGE
pour le schéma. USAGE
est une autorisation qui permet aux utilisateurs d’utiliser réellement les autorisations qui leur ont été attribuées. Quel est le but de ceci? Je ne suis pas sûr. Pour réparer:
# 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;
J'ai créé un script pratique pour cela; pg_grant_read_to_db.sh . Ce script accorde des privilèges en lecture seule à un rôle spécifié sur toutes les tables, vues et séquences d'un schéma de base de données et les définit par défaut.
Si votre base de données est dans le schéma public, cela est facile (cela suppose que vous avez déjà créé la variable 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
Si votre base de données utilise customschema
, exécutez la procédure ci-dessus mais ajoutez une commande supplémentaire:
db=> ALTER USER readonlyuser SET search_path=customschema, public;
ALTER ROLE
La manière la plus simple de le faire serait d’octroyer select à chaque table de la base de données:
postgres=# grant select on db_name.table_name to read_only_user;
Vous pouvez automatiser cela en générant vos déclarations de subvention à partir des métadonnées de la base de données.
CREATE USER username SUPERUSER password 'userpass';
ALTER USER username set default_transaction_read_only = on;
Tiré d'un lien posté en réponse à despesz ' link.
Postgres 9.x semble avoir la capacité de faire ce qui est demandé. Voir le paragraphe Accorder aux objets de base de données de:
http://www.postgresql.org/docs/current/interactive/sql-grant.html
Où il est indiqué: "Il existe également une option permettant d'octroyer des privilèges sur tous les objets du même type dans un ou plusieurs schémas. Cette fonctionnalité est actuellement prise en charge uniquement pour les tables, les séquences et les fonctions (mais notez que TOUTES LES TABLES sont considérées comme incluant des vues. et tables étrangères). "
Cette page traite également de l’utilisation des ROLE et d’un PRIVILEGE appelé "TOUS PRIVILEGES".
Des informations sur la manière dont les fonctionnalités de GRANT se comparent aux normes SQL sont également présentes.
J'ai lu toutes les solutions possibles, qui vont bien, si vous vous rappelez de vous connecter à la base de données avant d'accorder les choses;) Merci quand même à toutes les autres solutions !!!
user@server:~$ Sudo su - postgres
créer un utilisateur 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
démarrez psql cli et définissez un mot de passe pour l'utilisateur créé:
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
se connecter à la base de données cible:
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".
accorder tous les privilèges nécessaires:
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
modifier les privilèges par défaut pour les cibles db public shema:
target_database=# ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO readonly;
ALTER DEFAULT PRIVILEGES