|
Chapitre 34. Identification HTTP avec PHPVoici un exemple de script qui force l’identification du client pour accéder à une page :
<?php if (!isset($_SERVER['PHP_AUTH_USER'])) { header('WWW-Authenticate: Basic realm="My Realm"'); header('HTTP/1.0 401 Unauthorized'); echo 'Texte utilisé si le visiteur utilise le bouton d\'annulation'; exit; } else { echo "<p>Bonjour, {$_SERVER['PHP_AUTH_USER']}.</p>"; echo "<p>Votre mot de passe est {$_SERVER['PHP_AUTH_PW']}.</p>"; } ?>
<?php $realm = 'Restricted area'; //utilisateur => mot de passe $users = array('admin' => 'mypass', 'guest' => 'guest'); if (empty($_SERVER['PHP_AUTH_DIGEST'])) { header('HTTP/1.1 401 Unauthorized'); header('WWW-Authenticate: Digest realm="'.$realm. '",qop="auth",nonce="'.uniqid().'",opaque="'.md5($realm).'"'); die('Texte utilisé si le visiteur utilise le bouton d\'annulation'); } // analyse la variable PHP_AUTH_DIGEST if (!($data = http_digest_parse($_SERVER['PHP_AUTH_DIGEST'])) || !isset($users[$data['username']])) die('Mauvaise Pièce d\'identité!'); // Génération de réponse valide $A1 = md5($data['username'] . ':' . $realm . ':' . $users[$data['username']]); $A2 = md5($_SERVER['REQUEST_METHOD'].':'.$data['uri']); $valid_response = md5($A1.':'.$data['nonce'].':'.$data['nc'].':'.$data['cnonce'].':'.$data['qop'].':'.$A2); if ($data['response'] != $valid_response) die('Mauvaise Pièce d\'identité!'); // ok, utilisateur & mot de passe valide echo 'Vous êtes identifié en tant que : ' . $data['username']; // fonction pour analyser l'en-tête http auth function http_digest_parse($txt) { // protection contre les données manquantes $needed_parts = array('nonce'=>1, 'nc'=>1, 'cnonce'=>1, 'qop'=>1, 'username'=>1, 'uri'=>1, 'response'=>1); $data = array(); preg_match_all('@(\w+)=(?:([\'"])([^\2]+)\2|([^\s,]+))@', $txt, $matches, PREG_SET_ORDER); foreach ($matches as $m) { $data[$m[1]] = $m[3] ? $m[3] : $m[4]; unset($needed_parts[$m[1]]); } return $needed_parts ? false : $data; } ?>
Au lieu d’afficher simplement les variables globales “PHP_AUTH_USER” et “PHP_AUTH_PW”, vous préférerez sûrement vérifier la validité du nom d’utilisateur et du mot de passe. Par exemple, en envoyant ces informations à une base de données, ou en recherchant dans un fichier dbm. Méfiez-vous des navigateurs bogués, tels qu’Internet Explorer. Ils semblent très susceptibles en ce qui concerne l’ordre des en-têtes. Envoyer l’en-tête d’identification (”WWW-Authenticate”) avant le code de “HTTP/1.0 401” semble lui convenir jusqu’à présent. Pour éviter que quelqu’un écrive un script qui révèle les mots de passe d’une page, à laquelle on a accédé par une identification traditionnelle, les variables globales PHP_AUTH ne seront pas assignées si l’identification externe a été activée pour cette page. Dans ce cas, la variable “REMOTE_USER” peut être utilisée pour identifier l’utilisateur à l’extérieur. De même que “$_SERVER[’REMOTE_USER’]”.
Notez cependant que les manipulations ci-dessus n’empêchent pas quiconque possède une page non identifiée de voler les mots de passe des pages protégées, sur le même serveur. Netscape et Internet Explorer effaceront le cache d’identification client s’ils reçoivent une réponse 401. Cela permet de déconnecter un utilisateur, pour le forcer à saisir à nouveau son nom de compte et son mot de passe. Certains programmeurs l’utilisent pour donner un délai d’expiration ou, alors, fournissent un bouton de déconnexion.
<?php function authenticate() { header('WWW-Authenticate: Basic realm="Test Authentication System"'); header('HTTP/1.0 401 Unauthorized'); echo "Vous devez entrer un identifiant et un mot de passe valides pour accéder à cette ressource.\n"; exit; } if ( !isset($_SERVER['PHP_AUTH_USER']) || ($_POST['SeenBefore'] == 1 && $_POST['OldAuth'] == $_SERVER['PHP_AUTH_USER'])) { authenticate(); } else { echo "<p>Bienvenue : {$_SERVER['PHP_AUTH_USER']}<br />"; echo "Ancien : {$_REQUEST['OldAuth']}"; echo "<form action='{$_SERVER['PHP_SELF']}' METHOD='post'>\n"; echo "<input type='hidden' name='SeenBefore' value='1' />\n"; echo "<input type='hidden' name='OldAuth' value='{$_SERVER['PHP_AUTH_USER']}' />\n"; echo "<input type='submit' value='Re Authenticate' />\n"; echo "</form></p>\n"; } ?> Ce comportement n’est pas nécessaire par le standard d’identification “HTTP Basic”. Les tests avec “Lynx” ont montré qu’il n’affectait pas les informations de session lors de la réception d’un message de type 401. Ce qui fait que presser la touche “retour” (”back”) à un client “Lynx” précédemment identifié donnera l’accès direct à la ressource. Cependant, l’utilisateur peut utiliser la touche “‘_’” pour détruire les anciennes identifications. Notez également qu’avant PHP 4.3.3, l’identification HTTP ne fonctionne pas sous le serveur Mircosoft IIS avec la version CGI de PHP à cause d’une limitation de IIS. Pour que cela fonctionne en PHP 4.3.3+, vous devez éditer votre configuration de IIS ““Directory Security”“. Cliquez sur ““Edit”” et activez uniquement ““Anonymous Access”“, tous les autres champs doivent être laissés non actifs. Une autre limitation si vous utilisez le module IIS (ISAPI) et PHP 4, vous ne devez pas utiliser les variables “PHP_AUTH_*” mais à la place, la variable “HTTP_AUTHORIZATION” est disponible. Par exemple, utilisez le code suivant : “list($user, $pw) = explode(’:’, base64_decode(substr($_SERVER[’HTTP_AUTHORIZATION’], 6)));” Travail collaboratifContribuez, en ajjoutant des elements a cette page de manuel : Merci de votre aide |