Authentification php intrépide. HTTP Installer la sécurité sur une page en utilisant MySQL et PHP. Application. Textes sources des scripts

Pour envoyer un message "Authentification requise" au navigateur du client, ce qui entraînera à son tour une boîte de dialogue pour entrer un nom d'utilisateur et un mot de passe. Une fois que le client a entré son nom et son mot de passe, le script sera appelé à nouveau, mais avec les variables prédéfinies PHP_AUTH_USER , PHP_AUTH_PW et AUTH_TYPE , qui contiennent respectivement le nom d'utilisateur, le mot de passe et le type d'authentification. Ces variables se trouvent dans les tableaux $_SERVER et $HTTP_SERVER_VARS. Actuellement, seule l'authentification "de base" est prise en charge. Vous pouvez également lire une description plus détaillée de la fonction entête() .

Exemple de fragment de script qui force le client à se connecter pour afficher la page :

Exemple d'authentification HTTP

si (!isset($_SERVER [ "PHP_AUTH_USER" ])) (
entête( "WWW-Authenticate : domaine de base="Mon domaine"");

écho "Texte à envoyer si
si l'utilisateur a cliqué sur le bouton Annuler"
;
sortir;
) autre (
écho
"

Bonjour($_SERVER["PHP_AUTH_USER"]).

" ;
écho "

Vous avez saisi un mot de passe ($_SERVER["PHP_AUTH_PW"]).

"
;
}
?>

Remarque sur la compatibilité : Soyez particulièrement prudent lorsque vous spécifiez des en-têtes HTTP. Afin de garantir une compatibilité maximale avec le plus grand nombre de clients différents, le mot "Basic" doit être en majuscule "B", la région (domaine) doit être entourée de guillemets doubles (et non simples !), et exactement un espace doit précéder le code 401 dans le titre HTTP/1.0 401 .

Au lieu de simplement afficher les variables PHP_AUTH_USER et PHP_AUTH_PW à l'écran, vous devrez peut-être vérifier si elles sont correctes. Pour cela, utilisez la requête base de données ou rechercher un utilisateur dans un fichier dbm.

Vous pouvez observer les fonctionnalités du navigateur Internet Explorer. Il est très exigeant sur le paramètre des en-têtes transmis. Spécification d'en-tête Authentification WWW avant d'envoyer HTTP/1.0 status 401 est une petite astuce.

Depuis PHP 4.3.0, afin d'empêcher quelqu'un d'écrire un script révélant le mot de passe d'une page utilisant une authentification externe, les variables PHP_AUTH ne sont pas définies si cette page utilise une authentification externe et est défini sur le mode sécurisé. Quoi qu'il en soit, la variable REMOTE_USER peut être utilisée pour authentifier un utilisateur authentifié en externe. Vous pouvez donc toujours utiliser la variable $_SERVER["REMOTE_USER"].

Noter: PHP utilise la directive AuthType pour spécifier si l'authentification externe est utilisée ou non.

Il convient de noter que tout ce qui précède n'empêche pas que les mots de passe des pages nécessitant une autorisation soient volés par quiconque contrôle des pages sans autorisation situées sur le même serveur.

Netscape Navigator et Internet Explorer effacent tous deux le cache d'authentification de la fenêtre actuelle pour le domaine donné lorsqu'ils sont reçus du serveur. Cela peut être utilisé pour forcer l'utilisateur à se déconnecter et à réafficher la boîte de dialogue du nom d'utilisateur et du mot de passe. Certains développeurs l'utilisent pour limiter le temps de connexion ou pour fournir un bouton de déconnexion.

Un exemple d'authentification HTTP avec saisie forcée d'un nouveau couple identifiant/mot de passe

fonction authentification() ()
entête( "WWW-Authenticate : domaine de base="Tester le système d'authentification"");
en-tête("HTTP/1.0 401 non autorisé");
écho "Vous devez entrer un nom d'utilisateur et un mot de passe valides pour accéder à la ressource \n";
sortir;
}

Si (!isset($_SERVER [ "PHP_AUTH_USER" ]) ||
($_POST [ "SeenBefore" ] == 1 && $_POST [ "OldAuth" ] == $_SERVER [ "PHP_AUTH_USER" ])) (
authentifier ();
}
autre(
écho
"

Bienvenue : ($_SERVER["PHP_AUTH_USER"])
" ;
écho "Connexion précédente : ($_REQUEST["OldAuth"])";
écho "

\n";
écho "\n";
écho "\n";
écho "\n";
écho "

\n" ;
}
?>

Ce comportement n'est pas défini par les normes HTTP Basic Authentication, vous ne devez donc pas en dépendre. Comme les tests l'ont montré, le navigateur Lynx n'efface pas le cache d'autorisation lors de la réception d'un statut 401 du serveur, et en cliquant sur "Précédent" puis sur "Suivant" dans l'ordre, il est possible d'ouvrir une telle page, à condition que le les attributs d'autorisation n'ont pas changé. Cependant, l'utilisateur peut appuyer sur la touche "_" pour effacer le cache d'authentification.

Notez également qu'avant PHP 4.3.3, l'authentification HTTP ne fonctionnait pas sur les serveurs exécutant Microsoft IIS si PHP était installé en tant que module CGI, en raison de certaines restrictions IIS. Afin d'obtenir bon fonctionnement en PHP 4.3.3+, vous devez modifier le paramètre de configuration IIS appelé "Directory Security". Cliquez sur le libellé "Modifier" et cochez l'option "Accès anonyme", tous les autres champs doivent rester décochés.

Autre limitation si vous utilisez IIS via ISAPI : les variables PHP_AUTH_* ne sont pas définies, mais la variable HTTP_AUTHORIZATION est disponible. Exemple de code que vous pouvez utiliser : list($user, $pw) = exploser(":", base64_decode(substr($_SERVER["HTTP_AUTHORIZATION"], 6)));

Remarque concernant IIS : Pour que l'authentification HTTP fonctionne correctement dans IIS, l'option cgi.rfc2616_headers dans la configuration PHP doit être définie sur 0 (la valeur par défaut).

Attention: Dans le cas où le mode protégé est utilisé, l'UID du script actuel sera ajouté à la partie domaine de l'en-tête WWW-Authenticate.



<<< Назад Contenu Transférer >>>
Si vous avez d'autres questions ou si quelque chose n'est pas clair - bienvenue dans notre

Restreindre l'accès à certaines zones du site ressemble généralement à
monotone : chaque utilisateur reçoit un identifiant et un mot de passe ou lui-même
les sélectionne, et vous devez les saisir pour accéder à la partie sécurisée du site. D'un point de vue technique, la vérification du mot de passe utilise
différentes méthodes. Un formulaire HTML peut être utilisé pour entrer un nom d'utilisateur et un mot de passe.
Dans ce cas, le mot de passe est envoyé au serveur en clair dans la requête POST.
Ceci est inacceptable si l'utilisateur est en LAN lorsque cela est possible
à l'aide d'un renifleur. Pour résoudre ce problème, une méthode a été développée
authentification par hachage, dans laquelle le mot de passe n'est pas transmis, mais
une chaîne de hachage est transmise, en fonction du mot de passe, une seule fois
paramètre et, éventuellement, de tout autre paramètre. Cette méthode est encore
s'appelle défi/réponse car lorsque vous l'utilisez, le client
reçoit une demande avec un paramètre à usage unique et envoie une réponse contenant le hachage. Au niveau du protocole HTTP 1.1, l'authentification est possible en utilisant la méthode
Basique, ce qui n'est rien meilleure utilisation Formulaires HTML et Digest, qui
nous examinerons en détail.

Lors de l'utilisation de la méthode Digest, comme déjà mentionné, le mot de passe
n'est pas transmis et ne peut pas être reniflé, mais il y a un autre côté
Problèmes. Afin de vérifier le mot de passe, le serveur doit calculer
réponse et la comparer avec la réponse du client, par conséquent, le serveur doit
stocker le mot de passe ou les données qui en dépendent, nécessaires pour
passer l'authentification. Il s'ensuit qu'une personne qui a reçu des droits
pour lire les comptes (par exemple, en utilisant l'injection SQL), sera en mesure d'obtenir
accès aux pages protégées par la méthode Digest. Lors de l'utilisation de la méthode
De base il est possible de stocker des hashes à la place des mots de passe, ce qui ne permet pas de lever des droits,
après avoir lu ces hashes (nous verrons ci-dessous que Digest peut aussi stocker des hashes,
mais tels que leurs connaissances soient suffisantes pour calculer la réponse). Ainsi, nous sommes face à un dilemme : soit notre mot de passe sera sniffé,
ou ils l'obtiendront via une vulnérabilité Web que quelqu'un trouvera certainement,
car qui cherche trouvera toujours. Existe-t-il une méthode d'authentification sans
ces deux lacunes - la méthode d'authentification par clé publique :
vous avez besoin d'une clé publique pour la vérification et d'une clé secrète pour la vérification,
cependant, HTTP 1.1 ne fournit pas une telle méthode. RFC2069
recommande d'utiliser SSL si la sécurité est si importante. Seule la transmission du mot de passe est protégée, et le contenu n'est pas crypté, donc
que cela n'a aucun sens de protéger les ressources avec cette méthode, d'où l'utilisateur
reçoit information confidentielle. Ils nécessitent SSL. Et c'est logique
pour protéger, par exemple, un forum ou télécharger du contenu sur un site. Ainsi, si l'hébergement ne supporte pas le SSL, et l'authentification doit
pour être sûr, nous utiliserons Digest. Apache a un module mod_digest. Pour l'utiliser
dans la config (ou en .htaccess) on écrit :

AuthType Digest
AuthUserFile<файл>
AuthName<название защищаемой области>
Exiger valid_user

Les fichiers utilisateur sont créés par l'utilitaire
htdigest. Mod_digest a été signalé pendant un certain temps comme étant vulnérable, donc,
peut-être y a-t-il encore des problèmes à trouver. De plus, lorsque
J'ai essayé de l'utiliser à la maison, j'ai eu une erreur
500 Erreur interne du serveur. De plus, si l'ajout de comptes devait se produire
automatiquement, et il devrait y en avoir beaucoup, ils devraient
être stocké non pas dans la configuration Apache, mais dans MySQL. La solution -
utiliser php. PHP n'a pas de support intégré pour cela.
méthode, il faudra donc la mettre en œuvre. Pour cela, il faut étudier
cette méthode en détail. Je note tout de suite que l'article présenté dans cet article
l'implémentation ne fonctionne que sur Apache, puisque accès total aux gros titres
request (fonction apache_request_headers) ne fonctionne que dans Apache, mais sur
d'autres serveurs peuvent ne pas être disponibles. Nous avons juste besoin de lire
En-tête d'autorisation.

Description de la méthode

La description complète de la méthode se trouve dans la RFC 2069, et si
bref, la méthode fonctionne comme ça. Lorsque le serveur reçoit une demande relative à une zone protégée,
il génère une erreur 401 Autorisation requise et un en-tête de requête
authentification comme ceci :

WWW-Authenticate : Digest realm="zone sécurisée", nonce="123456123456"

royaume est le nom de la zone protégée et le nonce est la seule fois
sens. Il y a plus de paramètres facultatifs dont nous discutons
nous n'allons pas. Le client répète la requête avec un en-tête comme celui-ci :

Autorisation : Digest realm="zone sécurisée", nom d'utilisateur="123", uri="/index.php", nonce="123456123456", réponse="1234567890abcdef1234567890abcdef"

Le paramètre uri doit correspondre à l'URI de la requête et la réponse est
la réponse, qui se calcule ainsi :

réponse = H(H(A1) + ":" + nonce + ":" + H(A2))
H - fonction de hachage, MD5 par défaut
A1 = login + ":" + domaine + ":" + mot de passe
A2 = méthode de requête + ":" + URI
la méthode de requête est GET, POST, etc.

Comme vous pouvez le voir, A1 ne dépend ni de la requête ni de la
valeurs, de sorte que le serveur ne stocke peut-être pas le mot de passe, mais
H(A1). C'est ainsi qu'il est implémenté dans mod_digest dans Apache.
Cependant, les mêmes données sont suffisantes pour le client. L'agresseur, ayant reçu
ce hachage, peut calculer la réponse avec les formules ci-dessus et
générer une requête HTTP, par exemple, à l'aide du programme
AccessDriver et son outil HTTP
débogueur. Ce processus sera présenté plus en détail ci-dessous. Le serveur doit vérifier si la valeur est un nonce
celui qui a été précédemment délivré au client et s'il est périmé.
Si la réponse correspond au paramètre nonce, mais que la valeur de ce paramètre
non pertinent, la réponse décrite ci-dessus avec le code 401 est émise avec le seul
la différence est que l'en-tête WWW-Authenticate est ajouté avec le paramètre
stale=true indiquant que l'accès est refusé pour cette seule raison,
et doit réessayer sans demander à l'utilisateur de saisir un nouveau mot de passe. Ceci, à mon humble avis, n'est pas pratique, car si une telle situation se présente
lors de la demande d'un POST ou d'un PUT avec un gros bloc de données, le client devra
transférer toutes les données deux fois. Pour éviter cela, la norme prévoit
l'en-tête Authentication-Info, dans lequel le serveur peut, lorsqu'il répond à
une demande réussie informe le client du prochain nonce.
La syntaxe est la même que WWW-Authenticate, à l'exception du nonce
est remplacé par nextnonce. Cependant, à en juger par les résultats de mes
expériences, Opera ignore cet en-tête. Autre solution : selon
RFC 2068 (HTTP/1.1), le serveur PEUT répondre avant la fin de la requête,
afin que le client interrompe le transfert de données inutile, mais sur Apache+PHP cela
n'est pas implémenté, car le script ne commence à s'exécuter qu'après
comment Apache recevra et analysera entièrement la requête.

Stockage des données entre les requêtes

Il y a un point subtil dans l'implémentation PHP de la méthode challenge/response.
Le paramètre à usage unique est formé et envoyé au client en une seule réponse, et
coché déjà dans une autre session du script.
C'est-à-dire qu'il doit être sauvegardé d'un appel de script à l'autre, et pour cela il faut
utiliser des fichiers ou une base de données. Mon exemple utilise des fichiers nommés,
valeurs uniques correspondantes, et les fichiers eux-mêmes contiennent
Les adresses IP des clients auxquels ils sont délivrés. La collecte n'est pas implémentée dans l'exemple
poubelle : vous devez supprimer périodiquement les anciens fichiers.

Analyse de code

Ce script ne vérifie que le mot de passe et fonctionne indépendamment de
connexion. En fonction du succès du contrôle, des réponses simples sont émises.

$realm = "zone sécurisée" ; // Nom de l'aire protégée
$pass = "pass"; // Mot de passe
$fileprefix = "./"; // Chemin des fichiers d'étiquettes indiquant la validité du nonce

/* Construisons un paramètre à usage unique comme recommandé dans RFC2069, bien que cela soit possible d'une autre manière. Le paramètre, selon la recommandation, doit dépendre de l'adresse du client, de l'heure actuelle et de la chaîne secrète. */
$nonce = md5($_SERVER["REMOTE_ADDR"] . ":" . time() . ":MyCooolPrivateKey");

// Obtenir des en-têtes
$headers = apache_request_headers();

// Indicateur que nous définirons sur TRUE en cas de validation réussie
$auth_succès = FAUX ;
$périmé = "" ;

// S'il n'y a pas d'en-tête d'autorisation, alors il n'y a rien à vérifier
si (isset($headers["Autorisation"]))
{
$autorisation = $headers["Autorisation"] ;

/* Analysez le titre à l'aide d'une expression régulière. Le titre contient le mot "Digest" et une liste
paramètres de la forme param="value" ou param=value séparés par des virgules. Cette expression régulière correspond à l'un de ces paramètres.
*/
preg_match_all("/(,|\s|^)(\w+)=("([^"]*)"|([\w\d]*))(,|$)/",
$autorisation, $matches, PREG_SET_ORDER);

/* Maintenant, pour faciliter le traitement ultérieur, nous allons former un tableau, où les clés sont les noms des paramètres et les valeurs des éléments du tableau sont
valeurs des paramètres.
*/
$auth_params = tableau();
pour ($i = 0; $i< count($matches); $i++)
{
$match = $matchs[$i] ;

/* Le nom est toujours dans le second groupe de parenthèses, selon qu'il soit entre guillemets ou non, il peut
être dans le 4ème ou le 5ème groupe. Pour les groupes de crochets capturés
à une branche non réalisée, une chaîne vide dans le tableau,
vous pouvez donc simplement ajouter les valeurs.
*/
$auth_params[$match] = $match . $correspondance ;
}

/* Calculer la réponse qui correspond
le login saisi par l'utilisateur, notre mot de passe et le paramètre à usage unique passé par l'utilisateur.
*/
$a1 = $auth_params["nom d'utilisateur"] . ":" . $auth_params["domaines"] . ":" . $passe ;
$a2 = $_SERVER["REQUEST_METHOD"] . ":" . $_SERVER["REQUEST_URI"] ;
$resp = md5(md5($a1) . ":" . $auth_params["nonce"] . ":" . md5($a2));

// Nous vérifions la réponse.
si ($resp == $auth_params["response"])
{
//
Vérifier la pertinence d'un paramètre ponctuel
$fn = $fileprefix . $auth_params["nonce"] ;
si (@file_get_contents($fn) == $_SERVER["REMOTE_ADDR"])
{
unlink($fn); //
Cette option n'est plus pertinente.
$auth_success = TRUE ; //
Authentification réussie
) autre
{
// Le paramètre unique n'est pas pertinent
$stale = ", stale=true" ;
}
}
}

si ($auth_success)
{
imprimer(" Test d'authentification Digest

print("Authentifié avec succès\n");
var_dump($auth_params);

imprimer("");

) autre
{
file_put_contents($fileprefix . $nonce, $_SERVER["REMOTE_ADDR"]);

$proto = $_SERVER["SERVER_PROTOCOL"] ;
En-tête("$proto 401 non autorisé");
Header("WWW-Authenticate : Digest realm=\"$realm\", nonce=\"$nonce\"$stale");

imprimer(" Test d'authentification Digest

");
print("Vous devez vous authentifier avec la méthode Digest");
imprimer("
");
}

Passing Digest Auth avec H(A1) connu

Je vais montrer par exemple comment passer la vérification si le mot de passe est inconnu,
mais H(A1) est connu. Pour ce faire, comme déjà mentionné, vous avez besoin
AccessDriver. Je ferai des calculs de hachage en appelant depuis la ligne de commande
CLI PHP. Laissez la page protégée être située à
http://mrblack.local/auth1.php et le hachage H(A1) est "a8fb5b2d780a7bf0782207a51a013f04".

Ouvrez AccessDriver-> Outils-> Débogueur HTTP et entrez l'adresse
"http://mrblack.local/auth1.php". Cliquez sur "Se connecter". On a:

En-tête HTTP = HTTP/1.1 Autorisation 401 requise
En-tête HTTP = Date : Lundi, 04 juillet 2005 08:09:17 GMT
En-tête HTTP = Serveur : Apache/1.3.31 (Win32) PHP/5.0.2
En-tête HTTP=X-Powered-By : PHP/5.0.2
En-tête HTTP = WWW-Authenticate : Digest realm="zone sécurisée", nonce="5925bea78552224abda11bfe318a8a03"
En-tête HTTP = Connexion : fermer
En-tête HTTP = Type de contenu : text/html

Ouvrez la console, allez dans le dossier avec PHP et lancez la commande suivante :

php -r "imprimer md5("a8fb5b2d780a7bf0782207a51a013f04 :
: ".md5("GET:http://mrblack.local/auth1.php"));"

Nous obtenons la réponse Digest souhaitée : c6d0af0db239d75c
3f59640a4896d096
Maintenant, dans AccessDriver, cochez la case "Header Data", copiez-la dans le
les en-têtes de champ qui ont été envoyés dans la requête précédente, et les ajouter
Autorisation. Voici ce qui se passe :

GET http://mrblack.local/auth1.php HTTP/1.1
Accepter : image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, */*
Accept-Langue : en-us,en;q=0.5
Agent utilisateur : compatible avec Mozilla
Hébergeur : mrblack.local
Pragma : pas de cache
Autorisation : Digest username="mrblack", realm="zone sécurisée", nonce="5925bea78552224ab
da11bfe318a8a03", uri="http://mrblack.local/auth1.php", response="c6d0af0db239d75c3f59
640a4896d096"

Cliquez sur "Se connecter". On obtient le résultat :

Parfois, il est nécessaire de fermer l'accès extérieur PHP page si vous faites une zone fermée du site. Il peut s'agir d'une sorte d'informations cachées pour vos clients ou visiteurs du site, d'une sorte d'interface d'administration pour vous, etc. Vous pouvez proposer des centaines de tâches différentes qui nécessitent des restrictions d'accès.

Vous pouvez fermer une telle page de plusieurs manières complémentaires :

  1. Protection par mot de passe (login/mot de passe) à l'aide de variables $_SERVER["PHP_AUTH_USER"] et $_SERVER["PHP_AUTH_PW"].
  2. Protection par IP adresse client à l'aide d'une variable $_SERVER["REMOTE_ADDR"].
  3. Protection par MAC adresse dans les réseaux locaux (en plus de la protection par IP).

Analysons d'abord la première méthode, qui est la principale. Il vous permet de fermer l'accès à la page par identifiant et mot de passe, afin que seules les personnes connaissant l'identifiant et le mot de passe puissent y accéder. De plus, ils peuvent être divisés selon cette caractéristique et donner, respectivement, des informations différentes pour chacun. Implémenté en émettant des champs spéciaux dans l'en-tête du protocole HTTP. Créons une fonction auth_send():

" ,"

Erreur d'authentification

" ,"

Contactez votre administrateur pour obtenir un nom d'utilisateur et un mot de passe.

" ,""; sortie; ); ?>

Cette fonction informe le navigateur qu'une autorisation par login et mot de passe est nécessaire pour l'accès. Et donne également la page dans HTML pour l'utilisateur.

" ,"

Accueillir!

" ,"

Vous êtes connecté en utilisant le nom d'utilisateur ",$auth_user," et le mot de passe ",$auth_pass,"".

" ,""; ?>

Le code de vérification du login et du mot de passe n'est pas trop compliqué dans ce cas, car il est implémenté pour une seule personne. La logique de fonctionnement est simple s'il n'y a pas de variable $_SERVER["PHP_AUTH_USER"] et $_SERVER["PHP_AUTH_PW"] ou leurs valeurs ne correspondent pas à celles souhaitées, puis appelez la fonction auth_send(). N'oublie pas qu'il appelle à la fin sortir, donc le programme est terminé.

Le niveau de protection suivant est mis en œuvre en filtrant IP adresse du client de connexion. Bien sûr, sur Internet, de nombreux fournisseurs émettent IP adresses pendant un certain temps et il est inutile d'utiliser cette protection, mais si nous parlons de réseaux locaux d'entreprise, cette vérification fournira une protection supplémentaire.

Votre IP n'a pas été trouvée !!!"; exit; ); ?>

Ici dans la ligne $allowed_ips séparés par un espace IP adresses autorisées à accéder. Ensuite, nous obtenons un tableau en utilisant exploser() et faire une recherche de l'adresse du client à partir de $_SERVER["REMOTE_ADDR"]. j'ai utilisé la fonction recherche array_search(), car il est peu probable que son code implémenté en C s'exécute un peu plus vite que ce que nous pouvons écrire en PHPà l'aide de cycles pour ou pour chaque. Mais la vitesse n'est pas la chose principale ici :)

Et la dernière étape de la défense est de vérifier MAC adresses. Il appartient à la catégorie des paranoïaques et doit être utilisé si vous accédez depuis le réseau local et que les données que vous protégez sont vraiment très importantes. Jusqu'à présent, j'ai implémenté cette vérification uniquement sur le système linux en raison de la relative facilité de mise en œuvre. Mais vous pouvez essayer de l'implémenter pour n'importe quelle autre plate-forme. On écrit une fonction :

Comme Linuxoids l'a déjà compris, il est basé sur ARP table système, accessible à l'aide du fichier /proc/net/arp. La fonction recherche dans les chaînes les éléments requis IP adresse et renvoyez-la MAC adresse:

Votre IP=192.168.10.15 et MAC=00:04:31:E4:F8:37

Dans le système les fenêtres peut-être y a-t-il d'autres moyens d'obtenir MAC plus simple, mais de ceux qui fonctionnent vraiment, c'est la conclusion ARP tables système avec la commande :

C:\WINDOWS\>arp -a Interface : 192.168.10.15 sur l'interface 0x1000003 Adresse IP Type d'adresse physique 192.168.10.1 00-50-22-b0-6a-aa dynamique 192.168.10.2 00-0f-38-68-e9- e8 dynamique 192.168.10.3 00-04-61-9e-26-09 dynamique 192.168.10.5 00-0f-38-6a-b1-18 dynamique

Vous pouvez implémenter vous-même une protection basée sur cette adresse si vous en avez vraiment besoin :) Mais n'oubliez pas que si vous avez un équipement non géré sur votre réseau sans possibilité de liaison MAC adresses au port, cette protection peut ne pas fonctionner, car il est possible de falsifier toutes vos données d'identification utilisées pour la protection (login, mot de passe, adresse IP et MAC).

Introduction

Il s'agit d'un tutoriel qui devrait vous montrer les bases de la sécurisation de vos pages Web à l'aide de l'authentification HTTP. Au lieu de la méthode traditionnelle .htaccess (serveur Apache), nous allons utiliser MySQL pour stocker les données des utilisateurs et leurs mots de passe. Je vais essayer de tout mâcher autant que possible sur ce qui, à mon avis, est nécessaire pour qu'un débutant apprenne MySQL et PHP. En principe, vous pouvez utiliser n'importe quel SGBD (système de gestion de base de données) basé sur ce programme. Pourquoi cette méthode est-elle intéressante ? Eh bien, par exemple, ne serait-ce que parce que si vous utilisez une base de données, vous pouvez facilement n'autoriser qu'un certain groupe (personne) à avoir certains droits pour accéder à telle ou telle information. Si vous utilisez la méthode .htaccess traditionnelle d'Apache, vous devez ajouter manuellement les utilisateurs et le mot de passe dans le fichier de mots de passe. Un avantage cette méthode, bien .... jetez un oeil par vous-même.

Logiciel ce qui est nécessaire :

Plate-forme *nix (Linux, Unix, *BSD) PHP 3.0.x ou PHP 4.x MySQL (toute version)

Première étape

Allez-y, la première chose à comprendre est que nous voulons autoriser les utilisateurs qui se trouvent dans notre base de données à accéder à la page spécifiée ? Et comment allons-nous le faire ? (beaucoup de gens n'aiment pas vraiment ça, mais il faut s'habituer à prendre une feuille de papier avant de programmer et à écrire toutes les exigences que l'on veut obtenir du programme, à l'avenir vous gagnerez des heures voire des jours pour apporter des modifications au code (environ))

Vérifiez si l'utilisateur est déjà authentifié.

Sinon, envoyez un message au navigateur, avec le message et le formulaire d'accès.

Si l'utilisateur clique sur le bouton d'annulation, ne lui autorisez pas l'accès et redirigez-le vers... 403 : Accès refusé, ou affichez (cookie J) un message simple.

Si l'utilisateur a rempli la combinaison nom d'utilisateur et mot de passe, vérifiez-les Base de données MySQL données et assurez-vous qu'elles sont correctes, si elles sont positives, autorisez l'accès.

Si vous ne comprenez pas tout, ne vous inquiétez pas, cela deviendra clair plus tard (ou peut-être jamais) !

Deuxième étape - Création de notre base de données

Nous voulons que la base de données stocke les noms d'utilisateur (login) et le mot de passe de nos utilisateurs. Les champs requis peuvent facilement être ajoutés à une base de données existante, mais nous supposerons pour l'instant que vous n'ajoutez pas à une base de données existante mais que vous en créez une nouvelle. Le code suivant est une description de la façon de procéder. Supposition que si vous avez Apache sur votre ordinateur, vous pouvez commencer immédiatement :)

mysql> créer les membres de la base de données ;
mysql> créer des utilisateurs de table (
nom d'utilisateur varchar(25) NON NULL,
mot de passe varchar(15) NON NULL,
clé primaire (nom d'utilisateur),
nom d'utilisateur unique (nom d'utilisateur)
);

Nous avons maintenant une base de données pour stocker les utilisateurs, elle suppose un nom d'utilisateur jusqu'à 25 caractères et un mot de passe jusqu'à 15 caractères. (si cela ne vous convient pas pour une raison quelconque, définissez-le comme bon vous semble) Le nom d'utilisateur doit être "clé primaire" et être "unique" car nous ne voulons pas que 2 personnes ou plus aient le même nom d'utilisateur.

Veuillez noter que les noms d'utilisateur seront sensibles à la casse dans le cas suivant, l'utilisateur "Vasya" sera identifié différemment de l'utilisateur "vasya", autrement dit sensible à la casse. Nous allons maintenant ajouter un utilisateur test à MySQL afin de pouvoir l'utiliser pour les tests lors de la création de la page PHP.

mysql> accorder la sélection sur les membres. utilisateurs
à [courriel protégé]
identifié par "MyPassword" ;

C'est ainsi que lorsque nous voulons vérifier le nom d'utilisateur et le mot de passe d'une personne connectée à notre base de données, nous utiliserons l'utilisateur "httpuser" avec le mot de passe "MyPassword". Enfin, nous devons ajouter le nom d'utilisateur et le mot de passe de la personne à laquelle nous voulons autoriser l'accès.

mysql> insérer dans les utilisateurs value("john_doe", "eod_nhoj");

Je n'ai volontairement pas chiffré les données dans le programme, afin qu'en cas de perte du mot de passe, ne le déchiffre pas, et le simplifie au minimum :)) Ça y est, MySQL c'est fini, maintenant passons à autre chose !

Troisième étape - Écrire le code PHP

Avant de commencer, je décrirai brièvement ce que fera le paga. Lorsque vous arrivez sur une page sécurisée, le serveur enverra une requête et affichera une page pour entrer un nom d'utilisateur et un mot de passe. Si vous cliquez sur le bouton d'annulation ou entrez des données incorrectes, le serveur vous enverra (en-tête 401 non autorisé et refusera l'accès.) - c'est ainsi que l'invite traduit généralement la chaîne (en-tête 401 non autorisé et refuse l'accès) Je ne le ferai pas expliquer à mon avis on ne peut pas dire mieux !!! Dans le cas où vous entrez tout comme il se doit, il s'avérera que vous aurez simplement accès (ce qui devait être prouvé) Maintenant, le plus amusant, c'est le code même. Il est écrit délibérément avec des numéros de ligne, après que le code (ci-dessous) explique les lignes.

01 02
03 fonction access_denied() (
04 echo "401 Non autorisé : la combinaison nom d'utilisateur/mot de passe que vous avez saisie n'est pas valide.n" ;
05 }
06
07 fonction auth_headers($titre) (
08 Header("WWW-Authenticate : Basic realm="$title"");
09 En-tête("HTTP/1.0 401 non autorisé");
10 }
11
12 si(!isset($PHP_AUTH_USER)) (
13 auth_headers("Ma page Web protégée");
14 accès_refusé();
15 sortie;
16 }
17 autres (
18
19 $hostname = "localhost" ;
20 $nom d'utilisateur = "httputilisateur" ;
21 $password = "MonMotDePasse" ;
22 $base de données = "membres" ;
23
24 $query = "select username,password from users where username="$PHP_AUTH_USER" and password="$PHP_AUTH_PW"" ;
25 $link = mysql_connect($localhost, $username, $password) or die("Impossible de se connecter au serveur de base de données");
26
27 si (mysql_num_rows(mysql_db_query($database, $query)) == 0) (
28 auth_headers("Ma page Web protégée");
29 accès_refusé();
30 sortie;
31 }
32
33 mysql_close($lien);
34 }
35 ?>

C'est tout le truc - pokus, ça marche bien, vous pouvez l'utiliser où vous voulez, quand vous voulez et comme vous voulez, changer, améliorer, si vous parvenez à réduire le code à deux lignes tout en sauvegardant Fonctionnalité programme, alors assurez-vous de me l'envoyer !

Dans cette section, nous allons explorer rapidement chaque ligne pour éviter un échange houleux de questions dans les commentaires sur cet article à l'avance.

Ligne 3 :
Cette fonction affichera un message si "l'utilisateur malveillant" entre constamment les mauvaises données. J'en ai fait une fonction parce que nous l'utilisons deux fois et juste pour raccourcir le code source.

Ligne 7 :
Comme nous utilisons également cet en-tête deux fois, j'en ai également fait une fonction.

Ligne 8 :
Passez au navigateur un en-tête qui obligera l'utilisateur à entrer un nom d'utilisateur et un mot de passe. La variable $title sera affichée dans la boîte de dialogue de connexion.

Ligne 9 :
À la première demande, l'en-tête s'affiche ; lorsqu'il est annulé à nouveau, il affiche un message indiquant que l'accès est refusé.

Ligne 12 :
$PHP_AUTH_USER est une boucle qui affiche un message disant que le paga est protégé, et sortez !

Ligne 19-23 :
C'est quelque chose que personne d'autre que vous ne connaît, c'est-à-dire les moyens de se connecter à la base de données, le nom d'hôte, les noms de base de données, le nom d'utilisateur et le mot de passe. (pour la connexion MySQL)

Ligne 24 :
Requête MySQL qui renvoie les noms d'utilisateur et les mots de passe.

Ligne 25 :
Établissez une connexion avec MySQL et affichez une malédiction s'il n'y a pas de connexion !!! (cela signifie que vous avez quelque chose qui ne va pas dans les lignes 19-23, ou qu'il n'y a pas de MySQL du tout)

Ligne 27 :
Traiter $requête. S'il renvoie -0, cela signifie qu'une combinaison invalide a été saisie.

Ligne 33 :
Déconnectez la connexion MySQL.

Je recommanderais de stocker le code PHP dans un fichier nommé user_auth.php, user_auth.php3, ou... (votre fantasme ici) Supposons que nous ayons enregistré ce code dans le fichier user_auth.php. Chaque fois que nous voulons protéger soudainement notre page Web top secrète, nous incluons simplement ce fichier. La seule chose à laquelle je veux faire attention est que, logiquement, vous devez le connecter tout en haut de votre page PHP protégée, je vous conseille d'écrire ce qui suit à la ligne numéro 1 de votre page :

où "user_auth.php" est le nom du fichier sous lequel vous avez enregistré le code.

Votre question est la suivante : je n'utilise pas MySQL, que dois-je faire ?

Consultez l'administrateur de votre serveur, s'il s'avère être gentil, alors il vous aidera, pour lui c'est 5 minutes de travail, si le malin n'aide pas, alors rendez-vous sur le forum lié à la base de données que vous êtes utiliser et crier à l'aide ! Ou si vous vous considérez comme un programmeur normal, alors ... vous n'avez pas du tout besoin de ce code, et vous créerez des "sessions", crypterez avec PGP et pervertirez généralement comme si vous protégiez amazon.com