Octroi de privilèges pour une base de données particulière dans PostgreSQL

je me déplace de MySQL à PostgreSQL et j'ai heurté un mur avec des privilèges d'utilisateur. Je suis habitué à assigner à un utilisateur tous les privilèges à toutes les tables d'une base de données avec la commande suivante:

# MySQL
grant all privileges on mydatabase.* to 'myuser'@'localhost' identified by 'mypassword';

il me semble que le PostgreSQL 9.x solution implique d'attribuer des privilèges à un" schéma", mais l'effort exigé de moi pour comprendre exactement ce SQL à émettre se révèle excessif. Je sais que quelques heures de recherche donnera une réponse, mais je pense que tout le monde passant de MySQL à PostgreSQL pourrait bénéficier d'avoir au moins une page sur le web qui fournit une recette simple et complète. C'est la seule commande que j'ai jamais nécessaire de problème pour les utilisateurs. Je préférerais ne pas avoir à commander chaque nouvelle table.

Je ne sais pas quels scénarios doivent être traités différemment dans PostgreSQL, donc je vais énumérer certains des scénarios que j'ai généralement eu à gérer dans le passé. Supposons que nous voulons seulement modifier les privilèges pour une base de données unique qui a déjà été créée.

(1a) Pas toutes les tables ont été créées, ou (1b) les tableaux ont déjà été créés.

(2a), L'utilisateur n'a pas encore été créé, ou (2b) l'utilisateur a déjà été créé.

Les privilèges

(3a) n'ont pas encore été attribués à l'utilisateur, ou les privilèges (3b) ont été précédemment attribués à l'utilisateur.

(4a) l'utilisateur seulement doit insérer, mettre à jour, sélectionner et supprimer des lignes, ou (4b) l'utilisateur doit également être en mesure de créer et supprimer des tableaux.

j'ai vu des réponses qui accordent tous les privilèges à toutes les bases de données, mais ce n'est pas ce que je veux ici. S'il vous plaît, je suis à la recherche d'une recette simple, bien que je ne serais pas contre une explication aussi bien.

Je ne veux pas accorder de droits à tous les utilisateurs et à toutes les bases de données, comme cela semble être le raccourci classique, parce que cela l'approche compromet toutes les bases de données lorsqu'un utilisateur est compromis. J'héberge plusieurs clients de base de données et assigne à chaque client un login différent.

il semble que j'ai aussi besoin du privilège USAGE pour obtenir les valeurs croissantes d'une colonne serial , mais je dois l'accorder sur une sorte de séquence. Mon problème a plus de complexe.

17
demandé sur number5 2014-07-23 22:40:19

4 réponses

concept de base dans Postgres

Les rôles

sont des objets globaux qui peuvent accéder à toutes les bases de données dans un cluster de bases de données - étant donné les privilèges requis.

a cluster contient de nombreuses bases de données , qui contiennent de nombreux schémas . Les schémas (même avec le même nom) dans les différentes bases de données ne sont pas liés. L'octroi de privilèges pour un schéma ne s'applique qu'à ce schéma particulier dans les DB (DB au moment de l'octroi).

chaque base de données commence par un schéma public par défaut. C'est une convention, et de nombreux paramètres de départ. Autre que cela, le schéma public est juste un schéma comme les autres.

venant de MySQL, vous pouvez vouloir commencer avec un seul schéma public , ignorant effectivement la couche de schéma complètement. J'utilise régulièrement des douzaines de schémas par base de données.

Les schémas sont un peu (mais pas complètement) comme des répertoires dans le système de fichiers.

une fois que vous utilisez plusieurs schémas, assurez-vous de comprendre search_path paramètre:

"1519250920 par Défaut" privilèges

par documentation sur GRANT :

PostgreSQL accorde des privilèges par défaut sur certains types d'objets pour PUBLIC . Aucun privilège n'est accordé à PUBLIC par défaut sur les tables, colonnes, schémas ou tablespaces. Pour les autres types, la valeur par défaut les privilèges accordés à PUBLIC sont les suivants: CONNECT et CREATE TEMP TABLE pour les bases de données; EXECUTE privilège pour les fonctions; et USAGE privilège pour les langues.

toutes ces valeurs par défaut peuvent être changées avec ALTER DEFAULT PRIVILEGES :

rôle de groupe

comme @Craig a commenté , il est préférable de GRANT privilèges à un rôle de groupe et ensuite faire un membre utilisateur spécifique de ce rôle ( GRANT le rôle du groupe du rôle de l'utilisateur). de cette façon, il est plus simple de distribuer et de révoquer des paquets de privilèges nécessaires pour certaines tâches.

un rôle de groupe est juste un autre rôle sans connexion. Ajouter une connexion d'accès à la transformer en un rôle d'utilisateur. Plus:

Recette

dites, nous avons une nouvelle base de données mydb , un groupe mygrp , et un utilisateur myusr ...

Lorsqu'il est connecté à la base de données en question en tant que superutilisateur ( postgres par exemple):

REVOKE ALL ON DATABASE mydb FROM public;  -- shut out the general public
GRANT CONNECT ON DATABASE mydb TO mygrp;  -- since we revoked from public

GRANT USAGE ON SCHEMA public TO mygrp;

pour assigner a user all privileges to all tables comme vous avez écrit (je pourrais être plus restrictif):

GRANT ALL ON ALL TABLES IN SCHEMA public TO mygrp;
GRANT ALL ON ALL SEQUENCES IN SCHEMA public TO mygrp; -- don't forget those

pour définir les privilèges par défaut pour les objets futurs, exécutez pour chaque rôle qui crée des objets dans ce schéma:

ALTER DEFAULT PRIVILEGES FOR ROLE myusr IN SCHEMA public
GRANT ALL ON TABLES TO mygrp;

ALTER DEFAULT PRIVILEGES FOR ROLE myusr IN SCHEMA public
GRANT ALL ON SEQUENCES TO mygrp;

-- more roles?

maintenant, accordez le groupe à l'utilisateur:

GRANT mygrp TO myusr;

réponse connexe:

Alternatifs (non-standard)

venant de MySQL, et puisque vous voulez garder les privilèges sur les bases de données séparées, vous pourriez aimer ce paramètre non standard db_user_namespace . par documentation:

ce paramètre permet les noms d'utilisateurs par base de données. Il est désactivé par défaut.

lire attentivement le manuel. Je n'utilise pas ce paramètre. Il n'annule pas ce qui précède.

42
répondu Erwin Brandstetter 2017-05-23 11:47:17

peut-être pourriez-vous me donner un exemple qui accorde un utilisateur spécifique Sélectionner / Insérer/mettre à jour / supprimer sur tous les tableaux -- ceux existants et non encore créé -- d'une base de données spécifique?

ce que vous appelez une base de données dans MySQL ressemble plus à un schéma PostgreSQL qu'à une base de données PostgreSQL.

se Connecter à la base de données "test" en tant que super-utilisateur. Ici c'est

$ psql -U postgres test

modifier la droits par défaut pour l'utilisateur existant "testeur".

ALTER DEFAULT PRIVILEGES IN SCHEMA public
    GRANT INSERT, SELECT, UPDATE, DELETE ON TABLES
    TO tester;

Modifier les privilèges par défaut n'a aucun effet sur les tables existantes. C'est par la conception. Pour les tables existantes, utilisez la syntaxe standard GRANT et REVOKE.

vous ne pouvez pas attribuer de privilèges à un utilisateur qui n'existe pas.

1
répondu Mike Sherrill 'Cat Recall' 2014-07-24 00:34:27

Je ne veux pas accorder de droits à tous les utilisateurs et à toutes les bases de données, comme cela semble être le raccourci classique, parce que cette approche compromet toutes les bases de données lorsqu'un utilisateur est compromis. J'héberge plusieurs clients de base de données et assigne à chaque client un login différent.

OK. Lorsque vous assignez des tables au rôle correct, les privilèges accordés seront spécifiques au rôle et pas à tous les utilisateurs! Alors vous pourrez décider qui donner roles to.

  1. créer un role pour chaque base de données. Un rôle peut tenir de nombreux utilisateurs.
  2. puis assigner un client-username au rôle correct.
  3. assignez aussi your-username à chaque rôle si nécessaire.



(1a) tous les tableaux N'ont pas encore été créés, ou (1b) les tableaux ont déjà été créé.

OK. Vous pouvez créer des tableaux plus tard.

Lorsque vous êtes prêt, assignez des tables au bon client role .

CREATE TABLE tablename();
CREATE ROLE rolename;
ALTER TABLE tablename OWNER TO rolename;



(2a), L'utilisateur n'a pas encore été créé, ou (2b) l'utilisateur a déjà été créé.

OK. Créer les noms d'utilisateur lorsque vous êtes prêt. si votre client a besoin de plus d'un nom d'utilisateur, créez simplement un second client-username .

CREATE USER username1;
CREATE USER username2;



(3a) les Privilèges n'ont pas encore été affectés à l'utilisateur, ou (3b) les privilèges ont été précédemment attribué à l'utilisateur.

OK. Lorsque vous êtes prêt à donner des privilèges, créez l'utilisateur et assignez le correct rôle de de sa.

Utilisez la commande GRANT-TO pour attribuer des rôles aux utilisateurs.

GRANT rolename TO username1;
GRANT rolename TO username2;



(4a) l'utilisateur ne doit insérer, mettre à jour, sélectionner et supprimer que des lignes, ou (4b) l'utilisateur doit également être en mesure de créer et supprimer des tableaux.

OK. Vous exécutez ces commandes pour ajouter des autorisations à vos utilisateurs.

GRANT SELECT, UPDATE, INSERT, DELETE ON dbname TO role-or-user-name;
ALTER USER username1 CREATEDB;
1
répondu Red 2015-11-10 17:47:40

vous pouvez oublier le schéma si vous utilisez seulement le PUBLIC. Puis vous faites quelque chose comme ceci: ( voir doc ici )

GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }
    [, ...] | ALL [ PRIVILEGES ] }
    ON { [ TABLE ] table_name [, ...]
         | ALL TABLES IN SCHEMA schema_name [, ...] }
    TO { [ GROUP ] role_name | PUBLIC } [, ...] [ WITH GRANT OPTION ]
0
répondu Str. 2014-07-23 19:38:45