Authentification

From Dolibarr ERP CRM Wiki
Revision as of 19:43, 15 November 2006 by Ywarnier (talk | contribs) (→‎Processus)
Jump to navigation Jump to search

Introduction

Le système d'authentification de Dolibarr devient relativement complexe, et un bug peut être particulièrement difficile à trouver si l'on ne connaît par le processus d'authentification. Cette page présente une découpe du processus, qui permet de suivre la procédure et d'intervenir là où il le faut.

Processus

Le processus démarre par les inclusions de htdocs/index.php, qui est la première page que l'on charge pour s'authentifier dans Dolibarr. Pourtant, ce n'est pas index.php qui commence réellement le boulot, mais bien main.inc.php, inclut par pre.inc.php, lui même inclut par index.php. Nous avons donc:

<index.php >
  < pre.inc.php>
    <main.inc.php>
      <master.inc.php>
        #1#
      </master.inc.php>
      #2#
    </main.inc.php>
  < /pre.inc.php>
</index.php >
  1. 1# représente le chargement de tout un tas de librairie que nous utiliserons par la suite
  2. 2# représente l'exécution du login

L'exécution du login, elle, se présente comme suit:

$authmode=array('http','dolibarr');
if (isset($dolibarr_auto_user)) $authmode=array('auto');
// Si la demande du login a déjà eu lieu, on le récupère depuis la session
// sinon appel du module qui réalise sa demande.
// A l'issu de cette phase, la variable $login sera définie.
$login=;
if (! session_id() || ! isset($_SESSION["dol_user"]) || ! isset($_SESSION["dol_token"]))
{
 # Procédure de login #
}
else
{
   // On est déjà en session
   $login=$_SESSION["dol_user"];
}
// Charge l'objet user depuis son login
$result=$user->fetch($login);
if ($result <= 0)
{
    dolibarr_print_error($db,$langs->trans("ErrorCantLoadUserFromDolibarrDatabase"));
    exit;
}
// Est-ce une nouvelle session
if (! isset($_SESSION["dol_user"]))
{
   // Nouvelle session pour ce login
   dolibarr_syslog("New session in DOLSESSID_".$dolibarr_main_db_name.": ".session_id());
   $user->update_last_login_date();
   $_SESSION["dol_user"]=$user;
}

Encore une fois, le code de plus grande complexité a été extrait pour l'analyser plus en détail.

Toutefois, en passant au travers du code ci-dessus de façon rapide, quelque chose pourrait vous avoir sauté aux yeux. C'est l'objet $user.

Même si j'ai supprimé une grande partie du code du login ici, cet objet n'est pas déclaré dans ce script. En fait, il fait l'objet d'une instanciation au sein d'une méthode sur l'objet DOLIAuth, que nous verrons ci-dessous, et dont la classe est (re)définie dans htdocs/includes/pear/Auth/Auth.php. C'est lorsque l'on appelle la méthode start() sur cet objet que l'objet $user est instancié.

Mais analysons plus en détail le code d'appel de la méthode d'authentification (il y a plusieurs méthodes, donc plusieurs appels possibles et qui devraient être mutuellement exclusifs).

   session_name("DOLSESSID_".$dolibarr_main_db_name);
   session_start();
   // On est pas déjà authentifié, on demande le login/mot de passe
   // A l'issu de cette demande, le login et un jeton doivent avoir été placé
   // en session dans dol_user et dol_token et la page rappelée.
   // MODE AUTO
   if (in_array('auto',$authmode) && ! $login)
   {
       $login=$dolibarr_auto_user;
       dolibarr_syslog ("Authentification ok (en mode force)");
   }
   // MODE HTTP (Basic)
   if (in_array('http',$authmode) && ! $login)
   {
       $login=$_SERVER["REMOTE_USER"];
   }
   // MODE DOLIBARR
   if (in_array('dolibarr',$authmode) && ! $login)
   {
       require_once(DOL_DOCUMENT_ROOT."/includes/pear/Auth/Auth.php");
       $pear = $dolibarr_main_db_type.'://'.$dolibarr_main_db_user.':'.$dolibarr_main_db_pass.'@'.$dolibarr_main_db_host.'/'.$dolibarr_main_db_name;
       if ($conf->global->DATABASE_PWD_ENCRYPTED)
       {
           $cryptType = "md5";
       }
       else
       {
           $cryptType = "none";
       }
       $params = array(
           "dsn" => $pear,
           "table" => MAIN_DB_PREFIX."user",
           "usernamecol" => "login",
           "passwordcol" => "pass",
           "cryptType" => $cryptType,
       );
       $aDol = new DOLIAuth("DB", $params, "dol_loginfunction");
       $aDol->setSessionName("DOLSESSID_".$dolibarr_main_db_name);
       $aDol->start();         $result = $aDol->getAuth(); // Si deja logue avec succes, renvoie vrai, sinon effectue un redirect sur page loginfunction et renvoie false
       if ($result)
       {
           // Authentification Auth OK, on va chercher le login
           $login=$aDol->getUsername();
           dolibarr_syslog ("Authentification ok (en mode Pear Base Dolibarr)");
       }
       else
       {
           if (isset($_POST["loginfunction"]))
           {
               // Echec authentification
               dolibarr_syslog("Authentification ko (en mode Pear Base Dolibarr) pour '".$_POST["username"]."'");
           }
           else
           {
               // Non authentifie
               //dolibarr_syslog("Authentification non realise");
           }
           exit;
       }
   }
   // MODE LDAP
   if ($conf->ldap->enabled && in_array('ldap',$authmode) && ! $login)
   {
       // Authentification Apache KO ou non active, pas de mode force on demande le login
       require_once(DOL_DOCUMENT_ROOT."/includes/pear/Auth/Auth.php");
       $params = array(
           'dsn' => $ldap,
           'host' => $conf->global->LDAP_SERVER_HOST,
           'port' => $conf->global->LDAP_SERVER_PORT,             'version' => $conf->global->LDAP_SERVER_PORT,
           'basedn' => $conf->global->LDAP_SERVER_DN,
           'binddn' => $conf->global->LDAP_ADMIN_DN,
           'bindpw' => $conf->global->LDAP_ADMIN_PASS,
           //'userattr' => $conf->global->LDAP_FIELD_LOGIN_SAMBA,
           'userattr' => 'samAccountName',             'userfilter' => '(objectClass=user)',
       );
       $aDol = new DOLIAuth("LDAP", $params, "dol_loginfunction");
       $aDol->start();
       $result = $aDol->getAuth(); // Si deja logue avec succes, renvoie vrai, sinon effectue un redirect sur page loginfunction et renvoie false
       if ($result)
       {
           // Authentification Auth OK, on va chercher le login
           $login=$aDol->getUsername();
           dolibarr_syslog ("Authentification ok (en mode Pear Base LDAP)");
       }
       else
       {
           if (isset($_POST["loginfunction"]))
           {
               // Echec authentification
               dolibarr_syslog("Authentification ko (en mode Pear Base LDAP) pour '".$_POST["username"]."'");
           }
           else
           {
               // Non authentifie
               //dolibarr_syslog("Authentification non realise");
           }
           exit;
       }
    }

Pour cette analyse, nous ignorerons le mode http et le mode LDAP pour nous concentrer sur le mode dolibarr.