Intégration de l'authentification à deux facteurs avec CodeIgniter

Avec la récente série d'intrusions (hacks) de haut niveau chez Sony et d'autres sociétés, il est temps que vous examiniez de nouveau la sécurité de votre site Web. L’authentification à deux facteurs est un pas dans la bonne direction pour protéger votre site Web contre les pirates. Dans ce tutoriel, nous verrons comment l'implémenter dans notre application CodeIgniter.


Qu'est-ce que l'authentification à deux facteurs??

L'authentification à deux facteurs oblige les utilisateurs à utiliser quelque chose qu'ils connaissent, comme un nom d'utilisateur et un mot de passe, et quelque chose dont ils disposent, comme un téléphone, pour se connecter..

Dernièrement, des entreprises telles que Google et Facebook ont ​​mis en place une authentification à deux facteurs pour leurs utilisateurs. D'autres services, tels que MailChimp, utilisent d'autres formes d'authentification à deux facteurs pour aider à contrecarrer les attaquants. Mais encore, qu'est-ce que l'authentification à deux facteurs??

L'authentification à deux facteurs est un moyen de prouver votre identité en fonction de votre nom d'utilisateur et de votre mot de passe, ainsi que d'un périphérique physique que vous pouvez emporter avec vous..


L'application mobile de Duo prend en charge les notifications push pour l'authentification!

Cela rend beaucoup plus difficile pour les escrocs de voler votre identité, car ils auront besoin d'un accès à votre téléphone ou à votre jeton matériel - pas seulement à vos identifiants de connexion..

Heureusement pour vous, Duo Security propose un service gratuit à deux facteurs, idéal pour quiconque souhaite protéger son site Web..

Duo est non seulement gratuit, mais il regorge de fonctionnalités. Ils vous permettent de vous authentifier de différentes manières, notamment:

  • Authentification téléphonique
  • Jetons SMS
  • Générateur de jetons d'application mobile
  • Authentification Push
  • Jetons de matériel disponibles à l'achat

Étape 1: Configuration

Configuration CodeIgniter

Si vous n'avez pas encore travaillé avec CodeIgniter, je vous recommande fortement de consulter d'abord la série CodeIgniter From Scratch.

Ce tutoriel s'appuie sur le tutoriel Easy Authentication with CodeIgniter. Ce tutoriel sera beaucoup plus facile à comprendre si vous complétez le didacticiel précédent avant de continuer. Nous allons utiliser les fichiers de ce tutoriel comme point de départ.

Veuillez vérifier que votre config / autoload.php a les aides suivants en cours de chargement.

$ autoload ['helper'] = array ('url', 'form');

Créer un compte

Dirigez-vous vers Duo Security et créez-vous un compte.

Ils offrent un forfait gratuit pour les projets open source et pour les sites de moins de 10 utilisateurs Duo (un utilisateur Duo est une personne qui utilisera l'authentification à deux facteurs pour se connecter)..

Créer une intégration

Après vous être enregistré, vous devez vous connecter à Duo et créer une intégration. Une fois connecté, cliquez sur intégrations sur le panneau latéral pour afficher la page des intégrations. De là, cliquez sur le bouton "Nouvelle intégration".

Assurez-vous que l'intégration que vous créez est une intégration du SDK Web. Cela vous permettra d'utiliser leur API PHP avec CodeIgniter.

Le nom d'intégration est utilisé uniquement sur le site Web de Duo. Ceci est juste un moyen pour vous d'identifier votre intégration. Duo propose un guide de prise en main qui explique comment configurer une intégration..

Téléchargez le SDK Web

En plus de la configuration d'une intégration, vous devez télécharger le SDK Web..

Nous aurons besoin de deux éléments du SDK: un fichier PHP (duo_web.php) et un fichier JavaScript. Veuillez noter que le JavaScript a une dépendance jQuery et que le JavaScript fourni est livré avec jQuery..

Nous utiliserons le JavaScript fourni, mais notez que si ce n’est pas le cas, jQuery doit être chargé avant le JavaScript fourni par Duo. Pour plus d'informations sur le SDK Web et son fonctionnement, consultez la documentation à l'adresse http://www.duosecurity.com/docs/duoweb.


Étape 2: Modifications pour la sécurité

Une fois le didacticiel Easy Authentication with CodeIgniter terminé, vous devez disposer d’un système de connexion de base..

Meilleur hachage

Dans un premier temps, nous allons ajouter une fonction de hachage forte à la base de données. Openwall a une belle bibliothèque de hachage PHP qui implémente bcrypt. La dernière version de phpass est 0.3 au moment de cet article.

Allez-y et téléchargez phpass depuis leur site web: http://openwall.com/phpass/. Après avoir téléchargé et désarchivé le dossier, vous devrez le placer dans votre dossier de bibliothèques..

Nous allons maintenant avoir besoin de créer notre propre fichier de bibliothèque comme interface pour phpass. Créez un nouveau fichier de bibliothèque, nommé password.php. Notre bibliothèque aura deux fonctions:

  • une fonction de hachage pour ressasser les anciens mots de passe
  • une fonction check_password pour comparer les hachages avec les mots de passe en clair.
require_once ('phpass-0.3 / PasswordHash.php'); class Password var $ hasher; function __construct () // 8 est la force de hachage. Une valeur plus grande peut être utilisée pour plus de sécurité. // TRUE rend les mots de passe portables. FALSE est beaucoup plus sécurisé. $ this-> hasher = new PasswordHash (8, TRUE);  function hash ($ pass) return $ this-> hasher-> HashPassword ($ pass);  function check_password ($ pass, $ hash) retour $ this-> hasher-> CheckPassword ($ pass, $ hash); 

le Demandez une fois() déclaration assure que nous serons en mesure d'utiliser le PasswordHash classe de phpass.

PasswordHash prend deux arguments dans son constructeur:

  • un nombre indiquant la force de hachage
  • un booléen indiquant si les mots de passe doivent être portables ou non.

Dans ce cas, nous allons rendre nos mots de passe portables.

Cela signifie essentiellement que le hachage n'est pas aussi puissant, mais si nous devons un jour changer de serveur ou déplacer la base de données, nous pouvons en faire une copie. Si nous n'utilisons pas de schéma de hachage portable, nous risquons que tous nos utilisateurs créent de nouveaux mots de passe si la base de données est déplacée..

Remarque: Même si nous implémentons une fonction de hachage plus forte, vous devez toujours demander aux utilisateurs un mot de passe fort..

Modification du modèle d'administration

 fonction publique verify_user ($ email, $ mot de passe) $ q = $ ceci -> db -> où ('adresse_email', $ email) -> limite (1) -> get ('utilisateurs'); if ($ q-> num_rows> 0) $ result = $ q-> row (); $ this-> load-> library ('mot de passe'); // Assurez-vous que les hachages correspondent. if ($ this-> password-> check_password ($ password, $ result-> password)) return $ result;  return false; 

Auparavant, nous sélectionnions l'utilisateur en fonction de l'adresse électronique et du mot de passe haché. Nous extrayons maintenant l'utilisateur de la base de données en fonction de l'adresse de messagerie. Cela signifie que nous devons valider le mot de passe avant de pouvoir renvoyer l'utilisateur.

Après avoir extrait l'utilisateur de la base de données, nous allons charger la bibliothèque de mots de passe que nous venons de créer et vérifier que le mot de passe entré correspond au mot de passe haché..

Si les deux mots de passe correspondent, nous renvoyons l'utilisateur, sinon nous retournons faux.

Veillez à utiliser la bibliothèque de mots de passe pour créer un nouveau mot de passe par vous-même. Les mots de passe dans votre base de données seront invalides maintenant!

Modification de la table des utilisateurs

Nous allons ajouter un champ d'autorisation de base à la base de données. Cette autorisation déterminera si l'utilisateur se connectera ou non avec une authentification à deux facteurs.

Nous devons ajouter une colonne à la table des utilisateurs pour les autorisations à deux facteurs. Vous pouvez le faire via phpMyAdmin, ou en exécutant le code SQL suivant.

ALTER TABLE utilisateurs ADD two_factor_permission BOOLEAN NOT NULL;

Une valeur de 1 dans la colonne des autorisations obligera l'utilisateur à utiliser l'authentification à deux facteurs..

Le SQL ajoutera une colonne booléenne à la table des utilisateurs. Nous allons l'utiliser pour demander aux utilisateurs d'utiliser une authentification à deux facteurs ou pour la contourner..

Si vous avez bien fait cela, vous devriez voir une nouvelle colonne dans votre tableau d'utilisateurs. Vous devrez ensuite mettre à jour un enregistrement en cours ou insérer un nouvel enregistrement qui two_factor_permission à vrai (1).

Si cette colonne est définie sur faux (0), l'utilisateur pourra ignorer l'authentification à deux facteurs. C'est idéal pour les utilisateurs qui n'ont pas besoin du même niveau de sécurité qu'un administrateur.


Étape 3: Utilisation du paramètre d'autorisation

Nous aurons besoin d'un moyen de contourner l'authentification secondaire, ainsi que d'un moyen d'insérer une étape d'authentification secondaire dans le processus de connexion..

Contournement de l'authentification secondaire

Tout d'abord, nous aurons besoin d'un moyen de contourner l'authentification secondaire. Cela signifie que nous devrons inspecter l'utilisateur dans le contrôleur d'administration..

 if ($ res! == FALSE) $ _SESSION ['nomutilisateur'] = $ res-> adresse_email; if ($ res-> two_factor_permission) $ this -> _ second_auth ($ res-> email_address); revenir;  else $ _SESSION ['logs_in'] = TRUE; redirection ('bienvenue'); 

Ceci vérifie si l'utilisateur doit être connecté avec notre système à deux facteurs..

Si l'utilisateur doit utiliser une authentification à deux facteurs, nous voulons qu'il accède à la page d'authentification secondaire sans se connecter..

Au lieu de rediriger l'utilisateur, nous pouvons appeler le _second_auth () fonction et avoir que charger la page. Le "revenir"instruction évite de charger le formulaire de connexion.

Nous avons créé une nouvelle variable de session connecté que nous utiliserons pour vérifier que l'utilisateur est connecté. Cela signifie que nous devons apporter quelques modifications aux redirections..

Correction des redirections

Il y a deux redirections qui doivent être changées: la première est dans la fonction index du contrôleur admin.

if (isset ($ _SESSION ['notifié'] ') && $ _SESSION [' notifié '] === VRAI) redirect (' bienvenue '); 

L'autre est dans le Bienvenue manette. Nous devons nous assurer que l'utilisateur n'est pas connecté avant de rediriger.

if (! isset ($ _SESSION ['notifié'] ') || $ _SESSION [' notifié ']! == VRAI) redirect (' admin '); 

Insertion de l'authentification secondaire

Maintenant, nous devons gérer l'authentification secondaire.

dans le admin / index fonction, nous appelons _second_auth (), alors écrivons une fonction de base.

 public function _second_auth ($ username) echo "Bienvenue $ username, vous consultez une page d'authentification secondaire."; 

Étape 4: Construction de la vue

Les systèmes d'authentification traditionnels traitent les connexions comme un processus en une seule étape.

Duo nous donne un peu de JavaScript et HTML à injecter entre les deux étapes. Cela signifie que nous devrons créer une vue avec le code requis..

Créons une nouvelle vue, appelée second_auth.php dans le vues dossier. Pour que cela fonctionne, nous devrons insérer l'iframe et le code JavaScript fournis par Duo..

Vous devez créer une page avec la structure HTML de base. Les éléments suivants peuvent être placés dans le corps:

  

Dans une configuration typique, vous garderiez tout votre JavaScript dans un dossier de ressources. Ici, nous avons mis un Ressources dossier à la racine de notre site, avec un 'js'sous-dossier contenant le fichier JavaScript du SDK Web.

Notre src ressemblera:

src = "ressources / js / Duo-Web-v1.js "

Nous devons également ajouter ce second bit de JavaScript.

Nous allons générer ces données à partir du contrôleur sous peu.

Insérer un formulaire

Si vous avez suivi le didacticiel précédent, vous devriez avoir configuré CodeIgniter pour vous protéger contre CSRF..

Étant donné que le code JavaScript publiera des données sur notre contrôleur, CodeIgniter recherchera le jeton CSRF. Si nous n'avons pas ce jeton, nous aurons une erreur.

Le JavaScript que nous utilisons soumettra un formulaire avec l'identifiant "duo_form". Tout ce que nous devons faire est de le créer.

echo form_open ('admin', array ('id' => "duo_form")); echo form_close ();

En utilisant la classe de formulaire, CodeIgniter injectera automatiquement le jeton. Lorsque le formulaire sera posté, CodeIgniter trouvera le jeton et poursuivra..


Étape 5: Préparation des données

Retour dans le admin contrôleur, nous devons générer des données dans notre _second_auth () une fonction.

L'hôte est l'URL de l'API qui vous a été fournie lors de votre inscription à Duo. Cette URL devrait ressembler à quelque chose comme api-xxxxxxxx.duosecurity.com (où 'xxxxxxxx' est une chaîne unique liée à votre compte Duo).

$ data ['host'] = "api-xxxxxxxx.duosecurity.com";

N'oubliez pas de remplacer l'hôte par votre URL spécifique. L'URL ci-dessus ne fonctionnera pas.

L'action post est l'URL qui traitera la réponse une fois que l'utilisateur aura tenté de s'authentifier auprès de Duo..

Nous allons créer une autre fonction dans le contrôleur d'administration pour gérer le post-retour. Pour l'instant, nous allons nommer la fonction process_second_auth ().

 $ data ['post_action'] = base_URL (). "admin / process_second_auth";

Chargement du SDK Web PHP

Assurez-vous de renommer 'duo_web.php' en 'duo.php' pour éviter les erreurs CodeIgniter..

Si vous n'avez pas téléchargé la dernière copie de duo_web.php, vous pouvez l'obtenir à partir de la page Web SDK GitHub de Duo..

Parce que le SDK Web est une classe PHP, nous pouvons le renommer "duo.php"et placez-le dans notre dossier" application / libraries ".

Après avoir placé le fichier dans le dossier les bibliothèques dossier, nous pouvons le charger dans notre contrôleur.

 fonction publique _second_auth ($ username) $ this-> load-> library ('duo'); $ data ['host'] = "api-xxxxxxxx.duosecurity.com"; $ data ['post_action'] = base_URL (). "admin / process_second_auth"; echo "Welcome $ username, vous consultez une page d'authentification secondaire."; 

Générer la demande signée

Pour comprendre comment générer sig_request, vous devez comprendre ce que nous générons.

le $ akey la variable doit comporter au moins 40 caractères, sinon la bibliothèque Duo renverra une erreur!

Le kit SDK Duo Web crée deux jetons signés, l’un avec la clé secrète qu’ils vous fournissent, l’autre avec une clé d’application que vous créez..

sig_request est une combinaison des deux jetons.

En créant votre propre clé d'application, vous aurez une deuxième couche de sécurité. Un attaquant aura besoin à la fois de la clé secrète de Duo et de votre clé d'application personnelle pour usurper un jeton..

Nous allons maintenant générer le 'sig_request'. Duo vous fournira une clé d'intégration et une clé secrète lorsque vous créerez une intégration..

Assurez-vous de remplacer le texte ci-dessous par la clé d'intégration et la clé secrète qui vous ont été attribuées. Vous devez créer votre propre clé secrète. Il doit comporter au moins 40 caractères et être aussi aléatoire que possible..

fonction publique _second_auth ($ username) $ this-> load-> library ('duo'); // Clé d'intégration Duo $ ikey = "REMPLACEZ VOTRE CLÉ D'INTEGRATION DUO"; // Clé secrète Duo $ skey = "REMPLACER PAR VOUS UNE CLÉ SECRET DUO"; // clé d'application personnelle $ akey = "CRÉER UNE CLÉ D'APPLICATION"; $ data ['host'] = "api-xxxxxxxx.duosecurity.com"; $ data ['post_action'] = base_URL (). "admin / process_second_auth"; $ data ['sig_request'] = $ this-> duo-> signRequest ($ ikey, $ skey, $ akey, $ username); echo "Welcome $ username, vous consultez une page d'authentification secondaire."; 

Duo signRequest () va générer les jetons et les retourner sous forme de chaîne à transmettre à sig_request.

Nous devons maintenant charger les données dans la vue créée précédemment..

fonction publique _second_auth ($ username) $ this-> load-> library ('duo'); // Clé d'intégration Duo $ ikey = "REMPLACEZ VOTRE CLÉ D'INTEGRATION DUO"; // Clé secrète Duo $ skey = "REMPLACER PAR VOTRE CLÉ SECRET DUO"; // clé d'application personnelle $ akey = "CRÉER UNE CLÉ D'APPLICATION"; $ data ['host'] = "api-xxxxxxxx.duosecurity.com"; $ data ['post_action'] = base_URL (). "admin / process_second_auth"; $ data ['sig_request'] = $ this-> duo-> signRequest ($ ikey, $ skey, $ akey, $ username); $ this-> load-> view ('second_auth', $ data); 

Si vous essayez de vous connecter maintenant, vous devriez voir cette page:

Ceci est le formulaire d'inscription. Vous pouvez inscrire votre téléphone portable ici, mais nous n'avons rien pour traiter l'authentification secondaire afin qu'il ne vous connecte pas..

Si vous ne voyez rien du tout, affichez le source de la page pour les messages d'erreur. Toute erreur avec les données sera affichée dans le > étiquette.

Si le message "Accès refusé" est indiqué, assurez-vous d'avoir saisi la clé d'intégration et la clé secrète du site Web de Duo Security..


Étape 6: Traitement de l'authentification secondaire

Nous avons configuré notre post action pour être admin / process_second_auth, nous avons donc besoin de créer un process_second_auth () une fonction.

fonction publique process_second_auth () if (isset ($ _SESSION ['connecté_en']]) && $ _SESSION ['connecté_n' '] === TRUE) redirect (' bienvenue '); 

Puisque cette fonction aura sa propre URL, nous devons rediriger les utilisateurs connectés..

Nous devons charger à nouveau la bibliothèque Duo pour valider les données.

$ this-> load-> library ('duo'); // Même clé utilisée dans _second_auth () $ ikey = "REMPLACER PAR VOTRE CLÉ D'INTEGRATION DUO"; $ skey = "REMPLACEZ AVEC VOTRE CLÉ SECRET DUO"; $ akey = "REMPLACEZ AVEC VOTRE CLÉ D'APPLICATION";

Nous aurons besoin de la même chose $ ikey, $ skey et $ akey du _second_auth () fonction pour valider les données postées.

Le JavaScript affiche une sig_response des serveurs Duo.

$ sig_response = $ this-> input-> post ('sig_response'); $ username = $ this-> duo-> verifyResponse ($ ikey, $ skey, $ akey, $ sig_response);

Une fois que nous avons tiré sig_response à partir des données postées, nous les passerons à travers le verifyResponse () une fonction. Cela retournera NULL si les jetons ne correspondent pas, ou un nom d'utilisateur s'ils sont valides.

if ($ username) $ _SESSION ['log_in'] = TRUE; redirection ('bienvenue');  else redirect ('admin'); 

Enfin, nous vérifierons qu’un nom d’utilisateur a été renvoyé et finissons de les connecter en définissant la valeur de $ _SESSION ['log_in'] à vrai.

Dans l'ensemble, la fonction devrait ressembler à ceci:

fonction publique process_second_auth () if (isset ($ _SESSION ['connecté_en']]) && $ _SESSION ['connecté_n' '] === TRUE) redirect (' bienvenue ');  $ this-> load-> library ('duo'); // Même clé utilisée dans _second_auth () $ ikey = "REMPLACER PAR LA CLE D'INTEGRATION DE DUO"; $ skey = "REMPLACER PAR LA CLE SECRET DUO"; $ akey = "REMPLACEZ AVEC VOTRE CLÉ D'APPLICATION"; $ sig_response = $ this-> input-> post ('sig_response'); $ username = $ this-> duo-> verifyResponse ($ ikey, $ skey, $ akey, $ sig_response); if ($ username) $ _SESSION ['log_in'] = TRUE; redirection ('bienvenue');  else redirect ('admin'); 

Maintenant, vous devriez pouvoir vous connecter avec une authentification à deux facteurs, allez-y et essayez-le!


Conclusion

J'espère que vous avez configuré votre propre système d'authentification à deux facteurs pour CodeIgniter!

Que pourriez-vous faire d'autre? Il y a beaucoup à faire en termes de sécurité, mais l'amélioration la plus importante consisterait à suivre les actions des utilisateurs..

Un bon système de sécurité est non seulement sécurisé: il vous aidera à identifier la source d'une vulnérabilité. Gardez une trace des tentatives de connexion et des autres actions visant à faciliter l'identification des attaquants..

Merci d'avoir lu! Si vous rencontrez des problèmes, laissez un message dans les commentaires.