Sans persistance de l'authentification
Séquence d'authentification
Le couple login/mot-de-passe est transféré au CAS. La suite du processus se poursuit uniquement en cas d’authentification réalisée avec succès.
Le CAS renvoie un token d’authentification (TGT).
Le backend multi récupère le profil de l’utilisateur associé à son login. Un profil d’utilisateur contient la liste des différentes informations de l’utilisateur (nom, prénom, etc…) ainsi que les rôles dont il dispose.
L’ensemble token, login et roles (issus du profil utilisateur) sont stockés dans une base mongo.
Le token ainsi que le profil utilisateur est renvoyé en réponse à l’application mobile qui stockera le premier dans le “secure storage” et le second dans le cache de l’application (indexedDB).
Accès à une ressource protégée une fois authentifié
Dès lors que l’on souhaite accéder à une ressource protégée (souvent une API), le déroulement est le suivant :
L’application mobile récupère le token préalablement stocké dans le “secure storage” afin de l’envoyer dans la requête au serveur MULTI.
Le serveur récupère dans Mongo le login ainsi que les rôles de l’utilisateur associé à ce token.
Optionnellement des vérifications de droits liées au rôles de l’utilisateur peuven{t avoir lieu.
Le login est ensuite envoyé à la ressource protégée pour récupérer les informations propres à l’utilisateur connecté (exemple: API de récupération des cartes d'étudiant).
Pour finir, la réponse est envoyée à l’application mobile.
À noter
Le stockage du trio token, login et rôles en base Mongo permet au backend de récupérer le login ou les rôles depuis le token fournit par l’utilisateur. Cela permet de consolider la sécurité en évitant qu’un utilisateur malveillant ne manipule son login ou la liste de ses rôles.
Lorsque on enregistre un trio token, login et rôles en base Mongo une date-heure est mise à jour pour l’entrée concernée. Cela permet de nettoyer à terme les entrées considérées comme inactives depuis trop longtemps (la durée est configurable mais idéalement il est conseillé de mettre le temps d’expiration du token TGT).
Avec persistance de l'authentification
Enregistrement de l’authentification
L’enregistrement du couple login / mot-de-passe est déclenché lors de l’authentification réussie d’un utilisateur si le paramètre d’enregistrement est activé.
La clé de chiffrement est générée côté serveur puis “oubliée” dans la foulée (elle est transmise à l’application mobile au travers du payload du token JWT renvoyé en réponse à l’authentification).
L’UUID correspond à la clé primaire du couple login / mot-de-passe stocké en base de données.
Utilisation d’une authentification préalablement enregistrée
Lorsque l’on souhaite se ré-authentifier, il suffit à l’application mobile cliente de récupérer le JWT dans le Secure Storage et de l’envoyer au serveur. Ce dernier utilisera alors l’UUID+clé contenus dans le payload afin de déchiffrer le couple login / mot-de-passe et de le soumettre au serveur CAS pour ré-authentifier l’utilisateur.
A noter
Le chiffrement du couple login / mot-de-passe en base Mongo se fait selon l’algorithme AES-256. Il s’agit d’un chiffrement logiciel avant l’insertion de l’entrée en base, la base Mongo en elle même n’est pas chiffrée.
Chaque couple login / mot-de-passe utilise une clé de chiffrement différente.
Le serveur ne stocke pas les clés de chiffrement.
Ce système permet à un utilisateur d’enregistrer son authentification indépendamment sur plusieurs téléphone ou tablettes. Chaque appareil aura un UUID différent.
Lorsque on enregistre un couple login / mot-de-passe ou lorsqu’on en utilise un pour se ré-authentifier une date-heure est mise à jour pour l’entrée concernée en base Mongo. Cela permet de nettoyer à terme les entrées considérées comme inactives depuis trop longtemps (Cas d’un appareil perdu, d’une application désinstallée, etc…)
Implémentation et comportement de la réauthentificiation au niveau de l'App Frontend
L’application cliente dispose d'un intercepteur HTTP (shared/.../auth/auth.interceptor.ts
) pour les erreurs HTTP 401 (non autorisé) retournées par le backend.
Toutes les requêtes retournant une 401 sont interceptées et une ré-authentification est effectuée si le mot de passe avait été sauvegardé (sauf lors d’une tentative de login de l’utilisateur qui aurait échoué)
Exemple : sur une page lançant plusieurs requêtes nécessitant chacune l’envoi du token de l’utilisateur, si le token a expiré, ces requêtes se terminent en 401. L'intercepteur traite la première d'entre elles et entraîne une ré-authentification pendant que les autres restent en attente du résultat.
Si la ré-authentification réussit, ces requêtes sont automatiquement relancées et les résultats sont renvoyés aux observables correspondants.
Si la ré-authentification échoue (ou que l'utilisateur n'avait pas choisi de sauvegarder ses identifiants), le profil anonymous (= non authentifié) est chargé.
Les erreurs 401 ne sont plus interceptées par le app.error.handler tant que l'intercepteur est activé.
Pour l’utilisateur ayant sauvegardé ses identifiants la ré-authentification est donc invisible même si il elle se fait lors d’un changement de page. Cela est également valable lors de l'ouverture de l'app si le token a expiré depuis sa dernière visite.