Vous n'êtes pas identifié(e).
Pages : 1
J'ai l'impression qu'il y a un gros malentendu sur le vocabulaire. Une "table locale" ou "côté client" ici veut dire "implémenté avec le reste des objets SQL applicatifs créés sur la base de données", en opposition avec "utilisation de l'infrastructure existante dans postgres". Donc ici créer une table applicative pour gérer les utilisateurs plutôt qu'utiliser CREATE USER, créer une table applicative pour gérer les autorisation plutôt qu'utiliser GRANT / REVOKE (ou ROW LEVEL SECURITY ou autre) etc etc.
Effectivement il y avait malentendu mais c'est la phrase de alassanediakite "Donc la table est sur le serveur (dans la bd) et non sur le client (dans l'application cliente)" qui m'a fait tiquer.
Donc dans ma bdd "truc" j'ai créé une table "admin"."users" qui contient mes users et leurs hash et c'est bien une table locale à l'instance Postgres de ma bdd. Et une autre bdd (pour un autre projet) aura elle-aussi sa propre table "admin"."users". Ca je l'avais bien pigé. Ainsi si je veux déplacer ma bdd ailleurs, je fais un simple pg_dump de ma bdd truc.
Donc la table est sur le serveur (dans la bd) et non sur le client (dans l'application cliente).
Euh oui, exact La table est dans la bdd. Je ne savais pas qu'on pouvait implanter une table chez le client
Donc pour lui la table des users en local signifie sur l'application cliente. Ce que je trouve vraiment hyper compliqué à mettre en œuvre (implanter toute la gestion des privilèges coté client!).
Cela veut dire monter un second serveur Postgres chez le client ou alors j'ai rien pigé?
Enfin je suis un peu dépassé. Là j'ai une appli (qui est de type "portableApps"), je la dépose chez un client, il la lance, une fenêtre s'ouvre, il remplit les champs "ip", "port", "login", "mdp" et hop c'est connecté. Je ne vais pas lui faire installer un serveur Postgres...
La table es-elle en local comme l'a suggéré rjuju?
Oui. J'avais justement un schema "admin" qui contenait des tables d'admin (comme par exemple une table qui gère la licence, la clef de chiffrement, etc). J'y ai rajouté une table "users" avec le login et le hash du mot de passe.
Je me dit qu'avec un client en application desktop la mise à jour de la table locale peut être une casse-tête.
Ben j'avais déjà un petit programme indépendant qui me permet de rajouter un utilisateur. Je lui ai rajouté un insert/update/delete dans cette table. Comme je suis seul à créer des users ça va. Effectivement si la mise à jour est dévolue à toute une équipe et que certains n'ont pas l'info il peut y avoir désynchronisation.
Merci à tous de vos précieux conseils. @Gleu ok un schéma créé n'a aucun droit public j'ai enregistré l'info mais tel le débutant maladroit qui met ses variables à 0 même s'il les réinitialise 3 lignes en dessous, je préfère laisser mon revoke all on ... from public. Ca me rassure (ceci dit ça me fait relativiser quand j'évolue dans des forums de prog et que je vois justement écrit "int i=0" alors qu'il y a un for (i=0; ...; i++) juste en dessous).
Donc j'ai appliqué les conseils de rjurju. J'ai créé une table des users avec leur mot de passe. Ensuite quand le user veut changer son mot de passe, je checke la signature dans la table avant d'accepter ou pas. Un peu de travail en plus par rapport à ma première idée mais je suis content
Merci à tous.
Oui évidemment. Et par défaut un utilisateur n'a le droit que de créer des objets dans le schéma public, c'est donc assez facile à configurer (et c'est d'ailleurs recommandé, cf https://wiki.postgresql.org/wiki/A_Guid … earch_Path ).
Ok, j'ai regardé. Il se trouve que j'avais déjà verrouillé. En effet, déjà d'une part, aucune de mes tables n'est créée dans le schéma public. Déjà je commence même par tout supprimer from "public" au schéma public. Pusi ensuite, je crée des schémas dédiés aux grands domaines de ma bdd puis toutes, absolument toutes les tables sont créées dans ces schémas. J'ai même pensé à virer le schéma public mais j'ai eu peur qu'il soit malgré tout nécessaire à Postgres lui-même
Et ensuite, pour chaque schéma,je fais un "revoke all privileges from public" puis un "grant usage on user_de_base".
Et donc (j'ai testé l'exemple de la page), un user qui se connecte ne peut pas créer d'objet/fonction, ni dans public, ni dans un des schémas. J'ai quand-même pas mal verrouillé le truc quoi.
mais de manière générale si vous voulez vous assurer de n'autoriser que les requêtes applicatives, il ne faut autoriser que votre applicatif à se connecter.
Oui, c'est logique. Merci de tous ces conseils, ils ont été précieux :applo:
Je suis d'accord que vous avez fait les choses bien, mais malheureusement cette approche pose de nombreux problèmes, et à mon avis vous aurez un retour de baton un jour ou l'autre si vous gardez cette approche.
Hélas je n'ai pas assez de recul ni assez d'expérience. Mais je suis content que ce que j'ai fait ne soit déjà pas si mal.
Et bien déjà il aurait le droit de changer son mot de passe sans devoir fournir le mot de passe actuel, ce qui est en contradiction avec ce que vous cherchez à faire. Il aurait également le droit d'ouvrir autant de connexions qu'il le souhaite, jusqu'à saturation, et donc empêcher tout le monde de se connecter. Ou exécuter des requêtes de son choix et consommer énormément de ressources, potentiellement jusqu'à saturation ou OOM, ou de créer ses propres objets, insérer en une seule requêtes des milliards de lignes et saturer l'espace disque, désactiver les traces de requêtes etc...
D'accord, j'ai compris. Effectivement je n'ai vraiment pas assez d'expérience. Seul le changement de mot de passe en mode "sql" m'importe peu. Je ne vérifie pas le mot de passe pour l'embêter mais pour éviter qu'un idiot le lui change pendant qu'il va pissser. Si lui il veut le changer via la ligne de commande, ok pour moi.
Sinon effectivement tout un tas de possibilités auxquelles je n'ai pas pensé. Euh... il y a moyen de lui interdire de créer des objets via les grant? Et il peut vraiment désactiver les logs?
La distinction se ferait côté applicatif. Vous pouvez continuer à recevoir un utilisateur et mot de passe, et comparez ça avec une table locale contenant la liste des utilisateurs avec un secure hash du mot de passe. Votre applicatif retient alors l'utilisateur et autorise ou refuse les actions en fonction de son profil, également stocké dans des tables locales.
Pas mal du tout !!!
Merci de vos conseils, ils ont été précieux et considérés avec attention. D'autant plus que le projet en est à ses débuts donc je pose les bases ce qui veut dire que je peux les changer relativement facilement. Accessoirement (pour confirmation) il n'y a donc pas moyen de checker son propre mot de passe.
Super, merci de votre réponse
Désolé je débute dans ce forum.
Donc en ce qui concerne la connexion de l'appli avec le rôle fourni lors de la connexion, c'est exact. Toutefois ces rôles sont enregistrés dans postgres (je peux en rajouter ou en supprimer à volonté) mais seuls ces rôles peuvent s'y connecter.
Ensuite, l'utilisateur qui lance l'appli doit renseigner son identité + mot de passe, et ensuite l'appli effectue la connexion avec la bdd en fournissant ces informations.
Débutant en Postgres, j'ai quand-même tenté de faire les trucs bien en créant, dans la bdd elle-même, des roles dits "de groupe" (qui n'ont pas le droit login). Ces roles "de groupe" possèdent le droti "grant connect to". Ensuite les tables qui sont créées ont alors leurs droits insert/update/delete positionnés par rapport à ces roles "de groupe". Et les roles qui sont créés pour les utilisateurs sont ensuite "grantés" sur ces roles particuliers.
Voici par exemple comment est créé un nouveau role pour un utilisateur "toto" qui arrive
create role "toto" nosuperuser nocreatedb nocreaterole inherit login;
grant "sites_user" to "toto";
alter role "toto" password '123';
Le role "sites_user" étant donc ce role interne bdd, et ensuite tous les droits des tables sont gérés par rapport à ce "sites_user" dont "toto" hérite. Ensuite le monsieur "toto" arrive, je lui fournis "123" et il saisit "toto" + "123" dans les champs de l'appli et l'appli lui autorise ensuite l'accès (les menus se dégrisent, etc). En plus ça fonctionne bien quand "toto" se connecte, l'outil vérifie automatiquement les autorisations via postgres lui-même (requêtes "has_table_privilege()").
J'ai parfaitement conscience que cette méthode permettrait à toto de se connecter directement via psql (un petit linux portable qui usurperait l'IP des IP autorisées et hop) mais à quoi ça l'avancerait? Il n'aurait pas plus de droits via psql que ce qu'il en a avec l'appli. Les insert/update/delete qu'il ferait manuellement seraient les mêmes que ceux qui sont faits par l'appli et les logs Postgres enregistrairent ces insert/update/delete comme venant de "toto" comme il le fait quand ils viennent de l'appli avec "toto" qui y est connecté. Et "toto", qui est associé au role "sites_user", ne peut se connecter même en psql que sur la bdd pour laquelle "sites_user" possède le droit "connect". Question sécurité je pense être pas trop mal.
Mais effectivement mon appli n'est pas compatible avec un pooler de connexion (dont je connais la notion mais que je n'ai pas implémentée).
Mais à l'inverse, si l'appli se connectait avec un role dédié (que je présume donc directement créé avec la bdd), je ne pourrais plus gérer la connexion. Comment en effet distinguer "toto" de "titi"?
Bonjour à tous
Je suis en train de développer une application IHM. A un certain moment j'offre à l'utilisateur la possibilité de changer son mot de passe de connexion à la bdd. Je lui donne donc un champ "ancien mot de passe" à saisir et deux champs "nouveau mot de passe". Ok je checke que les nouveaux mots de passe sont identiques et différents de l'ancien puis je checke que l'ancien mot de passe est bon puis je lance un alter role ... password ... pour modifier le mot de passe en bdd.
Sauf que je ne sais pas comment faire l'étape "checker ancien mot de passe". Comment vérifier que le mot de passe entré est bien celui stocké dans pg_authid? En plus c'est l'IHM qui fait le check, IHM qui possède les droits de l'utilisateur lequel n'a pas le droit de lire pg_authid. Et pg_roles ne donne pas les mots de passe.
Je pourrais tenter une nouvelle connexion avec ce mot de passe et checker si la connexion est/n'est pas acceptée mais d'une part je trouve ça lourd et d'autre part mon appli pourrait bien tourner dans des environnements qui ne nécessitent pas de mot de passe pour se connecter (methode "trust" dans pg_hba.conf).
Pour l'instant ma solution c'est quand l'utilisateur se connecte, je stocke le mot de passe qu'il saisit dans un attribut de l'objet qui gère la bdd. Ensuite quand il veut changer, je checke si le mot de passe qu'il saisit est le même que celui qui est enregistré. C'est pas très propre mais je ne vois pas d'autre solution.
C'est quand-même dommage qu'il n'y ait pas une requête/fonction toute faite type "select current_password" tout comme il y a "select current_user". Ou même un simple "select verify_password_is 'est_ce_bien_celui_ci'". Je ne vois même pas de souci de sécurité car cette requête ne concernerait que l'utilisateur connecté.
Voilà. Si quelqu'un sait comment monter cette requête...
Merci à tous.
Pages : 1