Forum |  HardWare.fr | News | Articles | PC | Prix | S'identifier | S'inscrire | Aide | Shop Recherche
2014 connectés 

  FORUM HardWare.fr
  Programmation
  PHP

  [Résolu]Perte de connexion LDAP

 



 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[Résolu]Perte de connexion LDAP

n°2326192
LeMondeDor​t
Ah ?
Posté le 14-12-2018 à 11:49:35  profilanswer
 

:hello:
J'ai un souci sur mon application web. Je vous explique rapidement le contexte :
En gros mon appli se connecte à mon AD via le protocole LDAP afin que l'utilisateur puisse se logguer avec son nom d'utilisateur. L'appli récupère également d'autres infos dans l'annuaire ensuite, rien de foufou. Voici mon code :

Code :
  1. $logged=false;
  2. while (!$logged)
  3. {
  4. if (!isset($_SERVER['PHP_AUTH_USER']))
  5. {
  6.                 header('WWW-Authenticate: Basic realm="Connectez-vous avec vos identifiants XXX"');
  7.                 header('HTTP/1.0 401 Unauthorized');
  8.                 echo "L'authenfication avec vos identifiants XXX est obligatoire pour aller plus loin. Veuillez rafraîchir la page pour pouvoir saisir vos identifiants.";
  9.                 exit;
  10.         }
  11.         else
  12. {
  13.  //Connexion à l'AD
  14.                 $adServer = "ldap://XXXl";
  15.  $ldap = ldap_connect($adServer);
  16.  //On récupère la saisie de l'utilisateur via le WWW-Authenticate
  17.         $username = $_SERVER['PHP_AUTH_USER'];
  18.  $password = $_SERVER['PHP_AUTH_PW'];
  19.  //Chemin de l'utilisateur dans l'AD
  20.                 $ldaprdn = 'XXX'."\\".$username;
  21.                 ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
  22.  ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
  23.  //Bind permet de vérifier si dans le ldap choisi, le couple utilisateur/mdp existe
  24.  $bind = @ldap_bind($ldap, $ldaprdn, $password);
  25.                 ...La suite où je cherche l'utilisateur etc


Vous remarquerez que je me connecte en basic realm, c'est de l'interne inatteignable depuis l'extérieur donc la sécurité n'est pas forcément importante.  
 
ça marche bien, mais il y a un problème : au bout d'un certain temps (je ne sais pas l'estimer, c'est peut-être aléatoire - généralement ça arrive au bout d'un ou deux jours), il n'est plus possible d'utiliser l'appli : ça boucle sur le www-authenticate et il n'est donc plus possible d'aller plus loin. La solution pour faire repartir le tout : relancer la VM qui héberge la machine. Pas très pratique quand même :o
J'ai regardé les logs de notre AD il n'y a rien, la VM arrive à pinger le domaine donc pas de raison que ça foire... Faut-il que je passe à un mode de connexion plus sécurisé ? Une idée ?
Merci :jap:


Message édité par LeMondeDort le 03-01-2019 à 16:18:10

---------------
LMD
mood
Publicité
Posté le 14-12-2018 à 11:49:35  profilanswer
 

n°2326232
rufo
Pas me confondre avec Lycos!
Posté le 15-12-2018 à 10:00:20  profilanswer
 

Est-ce que tu fermes bien tes connexions ldap par la suite ? N'y aurait-il pas un nb max de connexions sur le ldap qui ferait qu'au bout d'un certain nb, ça bloquerait si elles n'étaient pas fermées ? Un effet cumulatif en fait...


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Cantine Calandreta : http://sourceforge.net/projects/canteen-calandreta
n°2326272
LeMondeDor​t
Ah ?
Posté le 17-12-2018 à 08:09:58  profilanswer
 

:hello:
Je ferme bien ma connexion LDAP avec @ldap_close($ldap). Cependant je me suis rendu compte que je la fermais à un endroit pas vraiment optimal : j'ai changé d'endroit la fermeture, on verra ce que ça donne dans 2/3 jours.


Message édité par LeMondeDort le 18-12-2018 à 16:26:06

---------------
LMD
n°2326343
LeMondeDor​t
Ah ?
Posté le 18-12-2018 à 16:25:51  profilanswer
 

Pas de plantage depuis hier 8h, peut-être une bonne nouvelle je sais pas encore :o


---------------
LMD
n°2326421
xrussianbe​autyx
Posté le 18-12-2018 à 21:51:55  profilanswer
 

Comme il y a cette sorte de boucle "while (!$logged)", ça serait utile que tu nous mettes la fin du else / de la boucle.

n°2326486
LeMondeDor​t
Ah ?
Posté le 19-12-2018 à 14:49:38  profilanswer
 

Le code complet :  

Code :
  1. <?PHP
  2. //Fonction permettant de se connecter via www-authenticate. La variable $logged permet de boucler si jamais les identifiants/mdp ne sont pas présents dans l'AD.
  3. function login()
  4. {
  5.         $logged=false;
  6.         while (!$logged)
  7.         {
  8.                 if (!isset($_SERVER['PHP_AUTH_USER']))
  9.                 {
  10.                         header('WWW-Authenticate: Basic realm="Connectez-vous avec vos identifiants XXX"');
  11.                         header('HTTP/1.0 401 Unauthorized');
  12.                         echo "L'authenfication avec vos identifiants XXX est obligatoire pour aller plus loin. Veuillez rafraîchir la page pour pouvoir saisir vos identifiants.";
  13.                         exit;
  14.                 }
  15.                 else
  16.                 {
  17.                         //Connexion à l'AD
  18.                         $adServer = "ldap://xxx";
  19.                         $ldap = ldap_connect($adServer);
  20.                         //On récupère la saisie de l'utilisateur via le WWW-Authenticate
  21.                         $username = $_SERVER['PHP_AUTH_USER'];
  22.                         $password = $_SERVER['PHP_AUTH_PW'];
  23.                         //Chemin de l'utilisateur dans l'AD
  24.                         $ldaprdn = 'xxx'."\\".$username;
  25.                         ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
  26.                         ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
  27.                         //Bind permet de vérifier si dans le ldap choisi, le couple utilisateur/mdp existe
  28.                         $bind = @ldap_bind($ldap, $ldaprdn, $password);
  29.                         if ($bind&&$password!='')
  30.                         {
  31.                                 //On choisit ce qu'on cherche dans l'AD
  32.                                 $attributes_ad = array("displayName","description","cn","givenName","sn","mail","co","mobile","company","displayName" );
  33.                                 //On cherche dans l'AD xxx
  34.                                 $base = "dc=xxx,dc=local";
  35.                                 $mail = $username."@xxx.com";
  36.                                 $result = ldap_search($ldap, $base, "mail=$mail*", $attributes_ad) or die ("Error in search query" );
  37.                                 $info = ldap_get_entries($ldap, $result);
  38.                                 //On récupère les résultats contenus dans le tableau
  39.                                 for ($i=0; $i<$info["count"]; $i++)
  40.                                 {
  41.                                         $user=$info[$i]["displayname"][0];
  42.                                 }
  43.                                 $_SESSION['name']=$user;
  44.                                 $_SESSION['user']=$username;
  45.                                 $logged=true;
  46.                         }
  47.                         else
  48.                         {
  49.                                 unset($_SERVER['PHP_AUTH_USER']);
  50.                                 unset($_SERVER['PHP_AUTH_PW']);
  51.                         }
  52.                         @ldap_close($ldap);
  53.                 }
  54.         }
  55. }
  56. ?>


De nouveau inaccessible ce matin, j'ai reboot la VM.


---------------
LMD
n°2326489
rufo
Pas me confondre avec Lycos!
Posté le 19-12-2018 à 14:58:08  profilanswer
 

Je trouve toujours un peu dangereux de mettre un while sans être sûr qu'on passera par la condition d'arrêt... Tu devrais inclure au moins un compteur limitant à 5 tentatives de connexions :o


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Cantine Calandreta : http://sourceforge.net/projects/canteen-calandreta
n°2326528
xrussianbe​autyx
Posté le 19-12-2018 à 19:14:50  profilanswer
 

C'est ça.
 
Il suffit d'une tentative de connexion avec des credentials erronés, et ta fonction tourne en boucle indéfiniment, à ouvrir/fermer des connexions ldap à la chaîne.
 
Et tu multiplies cela par le nombre de connexions utilisateur échouées, car à chaque fois ça rajoute une boucle infinie.
 
Donc tu mets à genoux à la fois ton serveur web (accumulation de threads php) et ton serveur ldap (gangbang d'ouvertures/fermetures de connexions).


Message édité par xrussianbeautyx le 19-12-2018 à 19:15:15
n°2326541
LeMondeDor​t
Ah ?
Posté le 20-12-2018 à 08:17:40  profilanswer
 

Hm je suis pas certain que ce soit la raison du problème, l'outil est très peu utilisé donc il ne devrait pas y avoir énormément de connexions concurrentes...
J'essaie malgré tout d'ajouter un compteur de nombre de connexion mais je n'y arrive pas :( j'imagine que le but est d'avoir une variable qui s'incrémente et qui casse la boucle si elle attend une certaine valeur, mais je ne sais pas pourquoi ma valeur ne va jamais au dessus de 2  :heink:

Code :
  1. $nb=0;
  2. while (!$logged||$nb!=5)
  3. {
  4.     $nb++;
  5. ... inchangé
  6. }
  7. if (!$logged&&$nb==5)
  8. echo "Erreur dans la sasie des identifiants. Veuillez saisir votre nom d'utilisateur (x.xxx) et votre mot de passe XXX pour vous connecter à Mayday. Vous pouvez rafraîchir la page pour réessayer.";


Message édité par LeMondeDort le 20-12-2018 à 08:18:46

---------------
LMD
n°2326558
mechkurt
Posté le 20-12-2018 à 10:22:13  profilanswer
 

Peut être pacque $nb!=5 est aussi vrai avec 0 1, 2, 3 et 4 ?
 
Essayes avec > ! ^^


---------------
D3
mood
Publicité
Posté le 20-12-2018 à 10:22:13  profilanswer
 

n°2326562
mechkurt
Posté le 20-12-2018 à 10:34:52  profilanswer
 

Peut être pacque $nb<=5 est aussi vrai avec 0 1, 2, 3 et 4 ?
 
Essayes avec > ! ^^


---------------
D3
n°2326570
LeMondeDor​t
Ah ?
Posté le 20-12-2018 à 10:43:01  profilanswer
 

Oui en effet c'était très con :o
Cela dit ça ne fonctionne pas mieux en mettant $nb>=5. J'ai l'impression que je sors de la boucle quoi qu'il arrive et que mon $nb est de nouveau fixé à 0 à un moment...
EDIT : je pense que c'est le exit; qui pose souci :

Code :
  1. if (!isset($_SERVER['PHP_AUTH_USER']))
  2. {
  3.     header('WWW-Authenticate: Basic realm="Connectez-vous avec vos identifiants XXX"');
  4.     header('HTTP/1.0 401 Unauthorized');
  5.     echo "L'authenfication avec vos identifiants XXX est obligatoire pour aller plus loin. Veuillez rafraîchir la page pour pouvoir saisir vos identifiants.";
  6.     exit;
  7. }


J'imagine que le exit; est exécuté quoi qu'il arrive et que du coup, ma fonction de login est reéxecuté et donc mes valeurs réinitialisées.


---------------
LMD
n°2326574
mechkurt
Posté le 20-12-2018 à 10:53:00  profilanswer
 

Le exit interrompt ton code complétement, si tu passes dans cette partie de ton if else rien d'autre ne sera exécuté...
 
C'est un peu le but de la function exit en fait.
 
Si tu veux sortir d'une boucle foreach, while ou do while tout en continuant a exécuter du code il faut utiliser l'instruction break.


---------------
D3
n°2326575
LeMondeDor​t
Ah ?
Posté le 20-12-2018 à 11:06:05  profilanswer
 

Bon j'ai corrigé mon truc en utilisant une variable de session pour compter le nombre d'essai. ça fonctionne, on est jetés si on se trompe trop de fois. A voir si ça corrige mon problème maintenant.


---------------
LMD
n°2326613
xrussianbe​autyx
Posté le 20-12-2018 à 13:12:44  profilanswer
 

Une variable de session parce que tu n'arrives pas à écrire une boucle correctement ? Oh mon dieu
 
Je viens de remarquer autre chose : si le ldap_bind() donne false (i.e. échec connexion), tu unset $_SERVER['PHP_AUTH_USER'] et $_SERVER['PHP_AUTH_PW'], alors les essais suivants ne risquent pas de fonctionner...

Message cité 1 fois
Message édité par xrussianbeautyx le 20-12-2018 à 13:17:26
n°2326614
MaybeEijOr​Not
but someone at least
Posté le 20-12-2018 à 13:19:46  profilanswer
 

De toute façon si un nouvel appel est effectué, il est obligé d'utiliser une variable de session (ou autre stockage en-dehors de la mémoire du script).


---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.
n°2326618
LeMondeDor​t
Ah ?
Posté le 20-12-2018 à 13:36:38  profilanswer
 

xrussianbeautyx a écrit :

Une variable de session parce que tu n'arrives pas à écrire une boucle correctement ? Oh mon dieu
 
Je viens de remarquer autre chose : si le ldap_bind() donne false (i.e. échec connexion), tu unset $_SERVER['PHP_AUTH_USER'] et $_SERVER['PHP_AUTH_PW'], alors les essais suivants ne risquent pas de fonctionner...


J'unset pour la boucle justement, sinon je vais essayer le même nom d'utilisateur et mot de passe en boucle et le www-authenticate ne réapparaîtra jamais. Et si, les essais suivant fonctionnent puisque le formulaire va de nouveau garnir les deux variables associées.
Je sais quelle est la différence entre un break et un exit merci bien :o par contre c'est le www authenticate que je n'ai jamais utilisé auparavant et je ne comprenais pas vraiment comment il fonctionnait. C'est réglé et mon compteur d'essai fonctionne désormais donc pas la peine de revenir dessus. On verra ce que ça donne avec la connexion au ldap.


---------------
LMD
n°2326626
xrussianbe​autyx
Posté le 20-12-2018 à 14:28:07  profilanswer
 

Je ne vois pas trop l'intérêt de la boucle, puisqu'en cas de credentials erronés il faut les redemander à l'utilisateur (i.e. nouvel affichage de la page). Le seul intérêt que je vois pour ce genre de boucle, ça serait pour effectuer plusieurs tentatives de connexion (avec un léger délai entre les tentatives) à un serveur AD qui serait capricieux.
 
Je suis très rapidement revenu sur ton code, sans vérifier sans tester sans rien, c'est juste si cela peut t'inspirer.
À noter que je tire profit du fait qu'il est inutile d'appeler ldap_close() si le script php exit juste après (en effet, php se charge de libérer les ressources sql etc. lorsque l'exécution du script est terminée)
 

Code :
  1. <?php
  2. //Fonction permettant de se connecter via www-authenticate.
  3. function login()
  4. {
  5.     $prompt = function ($title, $message) {
  6.         header('WWW-Authenticate: Basic realm="'.str_replace('"', '\\"', $title).'"');
  7.         header('HTTP/1.0 401 Unauthorized');
  8.         echo $message;
  9.         exit;
  10.     };
  11.     if (!isset($_SERVER['PHP_AUTH_USER']))
  12.     {
  13.         $prompt('Connectez-vous avec vos identifiants XXX', "L'authenfication avec vos identifiants XXX est obligatoire pour aller plus loin. Veuillez rafraîchir la page pour pouvoir saisir vos identifiants." );
  14.     }
  15.     //Connexion à l'AD
  16.     $adServer = 'ldap://xxx';
  17.     $ldap = ldap_connect($adServer);
  18.     //On récupère la saisie de l'utilisateur via le WWW-Authenticate
  19.     $username = $_SERVER['PHP_AUTH_USER'];
  20.     $password = $_SERVER['PHP_AUTH_PW'];
  21.     //Chemin de l'utilisateur dans l'AD
  22.     $ldaprdn = 'xxx'."\\".$username;
  23.     ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
  24.     ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
  25.     //Bind permet de vérifier si dans le ldap choisi, le couple utilisateur/mdp existe
  26.     $bind = @ldap_bind($ldap, $ldaprdn, $password);
  27.     if (!$bind || $password === '') {
  28.         $prompt('Échec connexion', "Vos identifiants n'ont pas été reconnus. Veuillez les saisir à nouveau." );
  29.     }
  30.     //On choisit ce qu'on cherche dans l'AD
  31.     $attributes_ad = ['displayName', 'description', 'cn', 'givenName', 'sn', 'mail', 'co', 'mobile', 'company', 'displayName']; // note : doublon "displayName"
  32.     //On cherche dans l'AD xxx
  33.     $base = 'dc=xxx,dc=local';
  34.     $mail = $username.'@xxx.com';
  35.     $result = ldap_search($ldap, $base, "mail=$mail*", $attributes_ad) or die ('Error in search query');
  36.     $info = ldap_get_entries($ldap, $result);
  37.     //On récupère les résultats contenus dans le tableau
  38.     for ($i = 0; $i < $info['count']; ++$i)
  39.     {
  40.         $user = $info[$i]['displayname'][0];
  41.     }
  42.     $_SESSION['name'] = $user;
  43.     $_SESSION['user'] = $username;
  44.     @ldap_close($ldap);
  45. }


Message édité par xrussianbeautyx le 20-12-2018 à 14:31:56
n°2326635
LeMondeDor​t
Ah ?
Posté le 20-12-2018 à 14:51:11  profilanswer
 

Merci pour ton temps, je vais regarder tout ça :jap:


---------------
LMD
n°2326651
mechkurt
Posté le 20-12-2018 à 15:11:58  profilanswer
 

LeMondeDort a écrit :

Je sais quelle est la différence entre un break et un exit merci bien :o


Loin de moi l'idée de te vexer, mais je suis pas devin et se tromper ainsi sur la sortie d'un while (exit en confusion entre < et > ) m’ont incité (a tort sans doute) à voir en toi un débutant...
 [:airforceone]  
Pour ma part, j'ai appris qu'on pouvait écrire et supprimer des $_SERVER, j'étais persuadé qu'elles étaient en lecture seul... ^^


---------------
D3
n°2326679
xrussianbe​autyx
Posté le 21-12-2018 à 01:07:55  profilanswer
 

Ça semble plutôt être un souci de compréhension du fonctionnement des requêtes HTTP.
 
En gros, une requête HTTP = une exécution du script PHP = une réponse HTTP renvoyée au client. Pour demander et tester de nouveaux credentials, il faut de nouvelles requêtes HTTP donc de nouvelles exécutions du script PHP.
 
@mechkurt : c'est possible mais évidemment très déconseillé. Le seul cas de figure acceptable que je vois, c'est un framework PHP qui irait normaliser les données, par exemple pour réduire les différences entre les différents serveurs HTTP.

Message cité 1 fois
Message édité par xrussianbeautyx le 21-12-2018 à 01:09:19
n°2327090
LeMondeDor​t
Ah ?
Posté le 03-01-2019 à 16:17:48  profilanswer
 

Bon en fait le souci était tout autre : c'était les DNS de ma VM qui faisaient de la merde  [:tinostar]
En accédant au LDAP non pas par son nom mais par son adresse IP ça marche à tous les coups... Voilà voilà :o


Message édité par LeMondeDort le 03-01-2019 à 16:17:58

---------------
LMD
mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  PHP

  [Résolu]Perte de connexion LDAP

 

Sujets relatifs
Erreur connexion à la database[EXCEL / VBA] Connexion ADO et recordset "limité"
Gérer une connexion $_SESSIONConnexion à travers un PC
Laravel connexion Facebookphp ldap add group
Connexion à la base impossible sur 1 PCConnexion base access MDE
lister les champs d'une table en connexion odbc[RESOLU] LDAP groupe
Plus de sujets relatifs à : [Résolu]Perte de connexion LDAP


Copyright © 1997-2018 Hardware.fr SARL (Signaler un contenu illicite) / Groupe LDLC / Shop HFR