Utiliser la ressource Authentification au sein d'un projet Easy2Do

Objectif et fonctionnalités de base
Cette ressource permet à un utilisateur de se connecter à une application Easy2Do.
Voici ses principales fonctionnalités :
- Connexion d'un utilisateur par le biais d'un identifiant et d'un mot de passe
- Génération d'un mot de passe temporaire lors de l'inscription puis changement par l'utilisateur lors de la première connexion
- Forcer l'utilisateur à modifier son mot de passe au terme d'un délai fixé
- Forcer l'utilisateur à saisir un mot de passe différent du précédent
- Affichage d'un indicateur de sécurité du mot de passe sous forme de jauge
- Possibilité de se substituer à un utilisateur (depuis une liste des utilisateurs par exemple)
- Possibilité de modifier son mot de passe
- Possibilité de réinitialiser son mot de passe si perdu
Doc & Ressources
Documentation d'origine
Doc d'origine sur SharePoint [↗]
Code source de la ressource
Exemple associé au cookbook
Installation
Les dépendances :
git submodule add -b release-2.18 git@bitbucket.org:doingfr/easy2do-core.git core
git submodule add -b release-3.0 git@bitbucket.org:doingfr/easy2do-module-base-de-donn-es.git ressources/base
La ressource :
git submodule add -b release-1.8 git@bitbucket.org:doingfr/easy2do-module-authentification.git ressources/authentification
Pour mettre à jour la DB avec les spécificités de la ressource, lancer une page du navigateur vers le site, avec /?bModeInstallModule=1&szModulesPourInstall=authentification.
Ou jouer simplement le SQL du fichier ressources/authentification/installation/installation.sql.
Un compte utilisateur est créé par défaut.
- identifiant :
doing - mot de passe :
doing42
La ressource Authentification hashe par défaut les mots de passe avec password_hash(<password>, PASSWORD_BCRYPT) (et password_verify() pour vérifier le mot de passe).
Usages
Activer une page de login dans chaque zone (privée, admin)
Par défaut, les applications disposant de la ressource authentification n'ont qu'une page de login activée. En fonction du type d'application défini dans les paramètres, cette page de login pourra être utilisée pour la partie privée ou la partie admin.
Toutefois, il est possible d'avoir besoin de plusieurs formulaires de login dans une application. On peut par exemple imaginer disposer d'une partie publique dans laquelle il est nécessaire de se connecter pour accéder à certaines fonctionnalités (poster un message, accéder à un contenu...) sans pour autant changer de zone; et d'une partie admin permettant d'administrer l'application. Il est fort probable dans ce cas-là qu'on ne souhaite pas utiliser le même formulaire pour les 2 pages de login (celle de la partie publique pourrait avoir une intégration plus travaillée, avec un lien "s'inscrire"). Dans le même genre on pourrait vouloir avoir une authentification pour la zone admin et une autre pour la partie privée.
Activer les pages de login des zones
La première étape consiste à indiquer que l'on souhaite utiliser une page de login spécifique à chaque zone.
Il va pour cela falloir surcharger la configuration de la ressource authentification.
Si ce n'est pas déjà fait, créez le fichier /modules/authentification/config/conf.yml.
Ajoutez ensuite ces lignes dans ce fichier conf.yml :
# Permet de définir quelles zones ont des formulaires d'authentification
aZonesFormulairesAuthentification:
admin: true
application: false
site: false
Il s'agit ici de la conf par défaut. Vous pouvez passer les valeurs à true pour activer les pages de login (pensez à relance un bResetCache=1).
Site permet d'accéder au formulaire de connexion de la partie publique. Url : /public/login
Application permet d'accéder au formulaire de connexion de la partie privée. Url : /prive/login
Admin permet d'accéder au formulaire de connexion de la partie admin. Url : /admin/login
Attention dans \APP\Modules\Authentification\Models\AuthUtilisateur::aGetCriteres, on a une vérification de taille minimale de MDP (8 caractères, cf. $aConfig['szMotDePasse']), qui semble être utilisée dans la connexion "publique", et par défaut le compte créé possède un MDP de 7 caractères.
Configurer les droits d'accès aux zones
Cette ressource ne permet pas de configurer des droits d'accès différents aux zones de l'application. Il faut coupler avec la ressource "Groupe" pour y parvenir.
Modifier les pages de login
Ça ne semble pas toujours bien fonctionner, malgré les bResetCache=1. À noter qu'il existe aussi des fichiers HTML dans le dossier ressources/authentification/vues. Mais sans forcément plus de succès.
Les templates des 3 pages de login sont dans 3 fichiers différents. Il est possible de les modifier en les surchargeant.
Pour ce faire, créez les fichiers à surcharger en fonction des zones souhaitées.
- site :
modules/authentification/templates/login-public/modele.html - application :
modules/authentification/templates/login-prive/modele.html - admin :
modules/authentification/templates/login/modele.html
On peut appliquer des styles spécifiques à chaque page de login en surchargeant le CSS. Chaque template a un CSS qui lui est propre :
- site : modules/authentification/templates/login-public/themes/defaut/css/signin.css
- application : modules/authentification/templates/login-prive/themes/defaut/css/signin.css
- admin : modules/authentification/templates/login/themes/defaut/css/signin.css
- attention, ce fichier est utilisé par plusieurs calques et sera donc inclus dans les 2 autres pages de login, pouvant résulter à des conflits de styles
Codes erreur lors de la connexion
Quand l'utilisateur tente de se connecter, la réponse du serveur est un objet JSON avec bSucces = true en cas de succès. Un échec peut s'accompagner d'un code erreur (clé szErreur).
- AUTH-001 : Erreur survenue dans la réutilisation d'un fingerPrint plus ancien. Fonction incriminée bReutilisationPlusAncienFingerprint dans APP\Modules\Authentification\Models\AuthUtilisateur
- AUTH-002 : FingerPrint Invalide. Fonction incriminée bValideFingerprint dans APP\Modules\Authentification\Models\AuthUtilisateur
- AUTH-003 : Erreur lors de insertion du fingerPrint. Fonction incriminée bInsertFingerprint dans APP\Modules\Authentification\Models\AuthUtilisateur
- AUTH-004 : Erreur dans l'envoi du mail de l'autorisation de connexion. Fonction incriminée bEnvoiMailAutorisationConnexion dans APP\Modules\Authentification\Models\AuthUtilisateur
- AUTH-005 : Erreur dans l'envoi du mail de limite de connexion atteinte. Fonction incriminée bEnvoiMailLimiteConnexionAtteinte dans APP\Modules\Authentification\Models\AuthUtilisateur
- AUTH-006 : Erreur dans l'envoi du mail d'une nouvelle connexion. Fonction incriminée bEnvoiMailNouvelleConnexion dans APP\Modules\Authentification\Models\AuthUtilisateur
- AUTH-007 : Erreur dans la récupération de l'utilisateur en DB. Fonction incriminée aConnexion
Empêcher l'utilisateur d'utiliser son précédent mot de passe
Lors d'un changement de mot de passe, il est possible d'empêcher l'utilisateur d'utiliser son précédent mot de passe. Pour cela, il faut activer la fonctionnalité dans la configuration du site.
Dans le fichier config/conf.yml, ajouter la ligne suivante :
bNouveauMdpDoitEtreDifferent: true
Lorsque l'utilisateur est invité à changer son mot de passe, s'il utilise le même mot de passe que précédemment, il recevra une erreur.
Il n'y a pas d'historique des mots de passe. Il est par exemple possible pour un utilisateur de changer une première fois son mot de passe par un nouveau, puis de revenir au premier lors du prochain changement.
Limiter la durée de vie des mots de passe
Pour plus de sécurité, on peut souhaiter faire en sorte que l'utilisateur soit invité à changer son mot de passe au bout d'un certain temps. Cette fonctionnalité est automatisée dans E2D.
Cette fonctionnalité utilise la colonne date_mot_de_passe de la table utilisateur.
Pour activer la gestion de la durée de validité des mots de passe, ajouter au fichier config/conf.yml la ligne suivante :
nDureeValiditeMotDePasse: 60 # durée en jours
Lors de la connexion, si le mot de passe de l'utilisateur est plus ancien que la durée définie, il sera invité à changer son mot de passe, ayant expiré. Une modale est affichée pour l'inviter à changer son mot de passe.
Il est possible d'activer ou désactiver à tout moment cette fonctionnalité, sans intervention dans la DB.
Cette fonctionnalité ne bloque pas réellement l'utilisateur dans sa connexion. S'il recharge la page au lieu de saisir son nouveau mot de passe, il arrivera sur l'accueil comme s'il venait de se connecter.
Gérer des mots de passe temporaires
Si on souhaite que l'utilisateur change son mot de passe lors de sa première connexion, il est possible d'utiliser un mot de passe temporaire (pour par exemple l'envoyer par email à l'inscription).
Cette option utilise la colonne mot_de_passe_temporaire de la table utilisateur.
La valeur par défaut de cette colonne est 1. Si la fonctionnalité est activée, il faudra donc penser à mettre cette valeur à 0 si on ne souhaite pas que l'utilisateur soit invité à changer son mot de passe lors de prochaine connexion.
Pour activer les mots de passe temporaires, ajouter au fichier config/conf.yml la ligne suivante :
bGestionMotDePasseTemporaire: true
Lors de la prochaine connexion de l'utilisateur la ressource va détecter si le mot de passe est temporaire et, le cas échéant, prévenir l'utilisateur qu'il doit changer son mot de passe (ouverture d'une modale avec un formulaire de remplacement du mot de passe).
Une fois modifié, le champ mot_de_passe_temporaire de l'utilisateur est mis à 0 et il ne sera plus invité à changer son mot de passe lors de ses prochaines connexions.
Tant que la fonctionnalité est désactivée, le champ mot_de_passe_temporaire n'est pas pris en compte, peu importe sa valeur.
Cette fonctionnalité ne bloque pas réellement l'utilisateur dans sa connexion, s'il recharge la page au lieu de saisir son nouveau mot de passe, il arrivera sur l'accueil comme s'il venait de se connecter.
Indiquer la force d'un mot de passe et le valider
Cette fonctionnalité permet d'ajouter une jauge indiquant la "force" du mot de passe que l'utilisateur est en train de saisir, mais aussi d'ajouter dans les critères de validation du formulaire des exigences plus poussées (force minimale, présence d'au moins une majuscule, d'une minuscule, d'un chiffre, etc.).
L'algorithme utilisé pour le calcul de la force se base sur celui fourni par le site http://www.passwordmeter.com/ (cf. ressources/authentification/JS/Authentification.js).
Il faut créer un élément HTML, d'ajouter dedans un élément de type <meter> avec la classe jauge_force_mdp et les attributs min=0, max=100, optimum=100, low=20 et high=40 (c'est pour la gestion des couleurs qui est automatique en html5), et ensuite d'ajouter un <label> avec la classe label_force_mdp (la structure autour de ces 2 élements est libre).
Exemple :
<div id="indicateur_force_mdp">
<meter min="0" max="100" optimum="100" low="20" high="40" class="jauge_force_mdp"></meter>
<label class="label_force_mdp"></label>
</div>
Dans le fichier JS de la page, pour dynamiser la jauge, il faut ajouter le code suivant :
const ePassword = oModal.eModal.find('#szNewPassword'); // Input du mot de passe
const eForceMdp = oModal.eModal.find('#indicateur_force_mdp'); // Conteneur qui contient la jauge et le label
const oAuthentification = new Authentification();
oAuthentification.vDynamiseIndicateurDeForceMdp(ePassword, eForceMdp); // Appelle la dynamisation de la jauge
Ajuster les règles jQuery Validate
En complément de la jauge, il est possible d'ajuster les exigeances du mot de passe (certaine force et suivant certaines contraintes).
Pour cela il faut surcharger la méthode \APP\Modules\Authentification\Models\AuthUtilisateur::aGetCriteres (dans un fichier modules/authentification/models/AuthUtilisateurSurcharge.class.php).
Pour la configuration szNewPassword ($aConfig['szNewPassword']), éditer l'entrée force_mdp avec la liste des critères souhaités (objet json).
Valeur par défaut de la ressource :
$aConfig['szNewPassword'] = array(
'minlength' => '8',
'maxlength' => '255',
'required' => '1',
'equalTo' => DBL_QUOTE.'.szConfirmationPassword_Changement_Mot_Passe'.DBL_QUOTE,
'force_mdp' => '{"sForceMin":"bon","aExigences":["majuscule","minuscule","chiffre"]}'
);
- sForceMin (facultatif) : Ce paramètre est une chaine de caractère qui définit la force minimale du mot de passe. Utilise les libellés que l'on peut trouver dans le label de la jauge, à savoir dans l'ordre du plus mauvais au meilleur : insuffisant, faible, bon, tres bon et excellent.
- aExigences (facultatif) : Ce paramètre est un tableau qui définit les exigences requises pour que le mot de passe soit valide.
- 4 exigences sont possibles :
- majuscule : au moins une majuscule
- minuscule : au moins une minuscule
- chiffre : au moins un chiffre
- symbole : au moins un symbole
Pour la longueur minimale et la longueur maximale, il faut utiliser les autres paramètres (au même niveau que force_mdp) : minlength et maxlength.
Identification via Fingerprint
TODO
Notes et remarques
La ressource embarque certaines fonctionnalités liées à d'autres ressources ou éléments non obligatoires (groupe, table ressource_droit).
Par exemple l'option restriction_acces (cf. ressources/authentification/config/conf.yml) pour la gestion des droits d'accès aux pages ou actions, via le fichier securite.yml.
Ceci ne sera pas abordé dans ce cookbook, mais il est important de le savoir pour ne pas être surpris.
À noter quelques problèmes connus :
- La vérification des droits d'accès aux actions, qui est cassée dans le fichier AuthentificationBrain.php
- cf.
if (isset($_REQUEST['szAction']) === true)dans lequel les clés à configurer ne sont jamais récupérées (l'ancien code commenté est lui fonctionnel).
- cf.