Jérôme Cutrona

Version statique de l'intranet de Jérôme Cutrona - Rejoindre la version dynamique 🔒

Les exemples et corrections sont potentiellement non fonctionnels.

B.U.T. Informatique - IUT de Reims - Université de Reims

Authentification et sessions - Sujet complémentaire

Navigation

Objectifs de la séance

  • Écrire une classe abstraite et la dériver
  • Effectuer une authentification sécurisée

Consignes

Ce sujet complémentaire est la suite du TP « Authentification et sessions ». Les questions seront logiquement traitées dans le même dépôt Git que le sujet principal.

Authentification sécurisée

Le but est de proposer une authentification sécurisée basée sur l'envoi par le serveur d'un challenge unique lors de la construction du formulaire de connexion. Ce challenge est mémorisé dans les données de session. Il est donc connu du client et du serveur.

Sur le client, le login et le mot de passe saisis par l'utilisateur sont encodés par SHA512 selon le principe suivant :

code = SHA512( concaténation( SHA512( mot_de_passe ), challenge, SHA512( login ) ) )
Le résultat de l'encodage sera affecté dans un champ caché « code » du formulaire avant l'envoi de ce dernier. Les champs de formulaire « login » et « pass » ne doivent pas faire partie des données envoyées, ils ne comporteront donc pas de nom (attribut HTML « name »).

Ainsi, ni le login, ni le mot de passe d'un utilisateur ne circulent en clair sur le réseau et, de plus, les données transmises par le client sont différentes à chaque connexion de l'utilisateur puisque le challenge sera nouveau à chaque production du formulaire. Le serveur peut cependant vérifier le couple identifiant / mot de passe en effectuant le même encodage que le client sur les données de la base de données au moment de sa requête de recherche du couple identifiant / mot de passe.

La logique chronologique des opérations sera la suivante : Authentification sécurisée

Travail à réaliser
  1. Avant de commencer à travailler sur l'authentification sécurisée, vous allez refactoriser votre classe « UserAuthentication » pour en extraire une classe abstraite « AbstractUserAuthentication » dont elle héritera :
    1. Recopiez votre classe « UserAuthentication » en « AbstractUserAuthentication »
    2. Dans « UserAuthentication », supprimez la propriété « $user »
    3. Dans « UserAuthentication », supprimez toutes les méthodes sauf « loginForm() » et « getUserFromAuth() »
    4. Dans « UserAuthentication », supprimez toutes les constantes sauf « LOGIN_INPUT_NAME » et « PASSWORD_INPUT_NAME »
    5. Dans « UserAuthentication », supprimez le trait « StringEscaper » si vous l'avez utilisé
    6. Faites hériter « UserAuthentication » de « AbstractUserAuthentication »
    7. Dans « AbstractUserAuthentication », supprimez le corps des méthodes « loginForm() » et « getUserFromAuth() » et rendez-les abstraites
    8. Dans « AbstractUserAuthentication », supprimez les constantes « LOGIN_INPUT_NAME » et « PASSWORD_INPUT_NAME » et changez la visibilité des autres constantes en « protected »
  2. Vérifiez que la mécanique d'authentification fonctionne toujours après cette refactorisation importante
    Remarque importante

    Cette refactorisation permet simplement de préserver la méthode d'authentification simple fonctionnelle et visible pendant que vous implémentez la version sécurisée. Dans la réalité, la variante simple ne serait plus utilisée si vous aviez codé la version sécurisée qui est bien plus pertinente.

  3. Déposez la classe « Random » (télécharger) dans le répertoire « src/Helper » de votre projet
  4. Téléchargez le fichier « sha512.js » (c'est un script du projet crypto-js) et placez-le dans un répertoire « js » à la racine de l'espace web de votre projet
  5. Créez la classe « SecureUserAuthentication » qui hérite de « AbstractUserAuthentication »
  6. Ajoutez-lui les constantes suivantes qui seront utiles pour la suite :
    • CODE_INPUT_NAME = 'code'
    • SESSION_CHALLENGE_KEY = 'challenge'
    • RANDOM_STRING_SIZE = 16
  7. Implémentez la méthode d'instance « loginForm(string $action, string $submitText='OK') » dans sa variante sécurisée :
    1. Faites un tirage aléatoire de taille « RANDOM_STRING_SIZE » à l'aide de la classe « Helper\Random » et stockez la valeur à la clé « SESSION_CHALLENGE_KEY » dans la session
    2. Produisez un formulaire contenant les champs de « login » (identifié, non nommé), « mot de passe » (identifié, non nommé) et « challenge » (identifié, non nommé et caché, ayant pour valeur la chaîne aléatoire) ainsi qu'un champ pour le « code » (identifié, nommé et caché)
    3. Insérez le script « js/sha512.js » dans la production de votre méthode
    4. Insérez dans la production de votre méthode, un script qui capture l'événement « onsubmit » du formulaire et effectue le codage SHA512 à partir du login, du mot de passe et du challenge et stocke la valeur dans code avant d'envoyer le formulaire
  8. Copiez votre script « form.php » en « secure_form.php » dans lequel vous instancierez un objet « SecureUserAuthentication » en lieu et place du « UserAuthentication » et vous modifierez l'action « auth.php » en « secure_auth.php », passée en paramètre de la méthode « loginForm() »
  9. Testez votre encodage en observant la requête HTTP générée, en particulier le contenu du corps de la requête qui contient les données postées : Requête HTTP lors de l'authentification sécurisée
  10. Créez la méthode « findByHashedCode(string $code, string $challenge) » dans la classe « User »
  11. Implémentez cette méthode avec la même logique que « findByCredentials() » mais en utilisant une requête préparée reproduisant le codage et comparant le résultat au code reçu
  12. Implémentez la méthode « getUserFromAuth() » dans sa variante sécurisée :
    • Récupérez la valeur du challenge dans les données de session
    • Utilisez la méthode « findByHashedCredentials(string $hashedCredentials, string $challenge) » de la classe « User »
    • Si le résultat est fructueux, créez une instance de « User » et mémorisez-la à l'aide la méthode « setUser() »
  13. Copiez votre script « auth.php en secure_auth.php » dans lequel vous instancierez un objet « SecureUserAuthentication » en lieu et place du « UserAuthentication »
  14. Testez votre authentification sécurisée