WebAuthn Mise en place d’une authentification WEB sans mot de passe

Le WebAuthn (pour Web Authentication) est un nouveau standard d’authentification pour les applications Web. Il s’agit d’une API standard, en place dans les navigateurs modernes, qui permet l'accès à des applications en utilisant des terminaux comme facteur d’authentification (téléphone et empreinte digitale / faciale, clé physique, PC et Windows Hello, etc.) Ce système existe grâce aux travaux de FIDO et du W3C qui ont mis en place le projet FIDO2 (reposant sur des principes de cryptographie) afin de standardiser ce mode de fonctionnement dans tous les navigateurs.

Son objectif principal est de venir remplacer l’utilisation de mots de passe qui entraîne de nombreux risques (brute force, réutilisation du même sur plusieurs sites, faible complexité, etc.) tout en proposant une solution standardisée.

Avant de s’attaquer à la mise en place d’un cas d’usage simplifié, nous allons voir les principes clé concernant sa mise place sous deux angles : enregistrement et authentification.

Fonctionnement de l'enregistrement via WebAuthn

Afin de pouvoir utiliser l’authentification via WebAuthn pour un utilisateur d’une application, la première étape consiste à activer (et donc enregistrer) les informations de connexion liées au terminal désiré.

On retrouve alors 3 éléments (de gauche à droite) :

  1. L’authentificateur (Windows Hello, Google Password Manager Android, etc)
  2. Le frontend de l’application web (via navigateur)
  3. Le backend de l’application web

WebAuthn - Mise en place d’une authentification WEB sans mot de passe
Schéma du fonctionnement de l’enregistrement WebAuthn (source : okta)

1. L’utilisateur (déjà authentifié dans l’application) clique sur un bouton “Activer WebAuthn” qui déclenche un appel API au serveur.

2. Le serveur génère un “challenge” qui contient les informations de l’utilisateur connecté (nom et identifiant unique) et le nom de domaine.

3. Ces éléments sont envoyés dans un retour API du serveur au client.

4. Le client récupère les éléments et utilise l’API du navigateur pour déclencher l’utilisation de l'authentificateur.

5. Le navigateur propose à l'utilisateur de choisir le type d’authentification qu’il souhaite activer (empreintes digitales par exemple) et son consentement. Une fois validé, l’authentificateur enregistre les éléments reçus et génère un identifiant, une clé privée et publique ainsi qu’une signature.

6. L’application web va alors pouvoir envoyer sous forme d’un deuxième appel API au serveur l'identifiant, la clé publique et la signature générée.

7. Les éléments sont persistés côté serveur (dans une base de données) et le challenge est invalidé.

Fonctionnement de l'authentification

Maintenant que l’utilisateur a enregistré les informations, celui-ci est en mesure de se connecter à l’application web.

WebAuthn - Mise en place d’une authentification WEB sans mot de passe
Schéma du fonctionnement de l’authentification WebAuthn (source : okta)

1. L’utilisateur (non authentifié dans l’application) clique sur un bouton “Se connecter”  qui déclenche un appel API au serveur.

2. Le serveur génère un “challenge”.

3. Il est envoyé dans un retour API du serveur au client.

4. Le client reçoit les informations et déclenche l’authentification via une API du navigateur. L’authentificateur reçoit les informations et envoie une invitation à l’utilisateur pour se connecter (apparition de l’écran de saisie de l’empreinte digitale par exemple) puis génère une signature cryptographique.

5. La signature est envoyée via un appel API au serveur.

6. Le serveur vérifie et déchiffre la signature, récupère l’utilisateur lié, invalide le challenge et retourne des informations d’authentification (un JWT par exemple).

7. L’utilisateur est maintenant connecté.

Cas d'usage simplifié

Maintenant que nous avons vu la théorie, nous allons pouvoir mettre en pratique à travers un cas d’usage simplifié, pour ne voir que les éléments essentiels.

Nous utiliserons NodeJs dans sa version v18.12.

Nous allons nous baser sur deux sous projets :

  • Un front en ReactJs (v18.2)
  • Un back en NestJs (v9.0)

Pour nous accompagner, nous utiliserons la bibliothèque SimpleWebAuthn qui nous aidera grandement pour la mise en place du WebAuthn, à la fois côté front que côté back.

Notez tout de même que cette bibliothèque fonctionne dans n’importe quel framework front et back, tant qu’il s’agit de Javascript ou Typescript.

Backend - NextJs

Tout d’abord, veuillez commencer par générer un projet NestJs vide en vous basant sur la documentation officielle.
Ensuite, il nous faudra installer les éléments suivants :

WebAuthn - Mise en place d’une authentification WEB sans mot de passe

Nous allons ensuite écrire les éléments suivants dans le fichier “app.controller.ts” :

WebAuthn - Mise en place d’une authentification WEB sans mot de passe

Les deux premières routes concernent l’enregistrement du WebAuthn :

  • Génération du challenge d’inscription
  • Inscription de l’authentification

Dans une vraie application, ces deux routes sont disponibles uniquement pour un utilisateur déjà authentifié. Ici, nous simulons ce principe en indiquant le nom de l’utilisateur en dur.

Les deux dernières routes concernent l’authentification. Il s’agit donc de routes publiques :

  • Génération du challenge de connexion
  • Authentification

Puis nous allons nous attaquer au cœur du backend, le fichier “app.service.ts” qui contiendra toute la logique de manipulation côté serveur du WebAuthn.

Nous aurons tout d’abord besoin des imports suivants :

WebAuthn - Mise en place d’une authentification WEB sans mot de passe

Puis différentes variables de configuration :

WebAuthn - Mise en place d’une authentification WEB sans mot de passe

Nous allons commencer par écrire deux variables de classes qui viendront faire office de base de données. Dans une véritable application, les éléments devraient être persistés dans une base de données. Vous pouvez également noter le “TODO” sur la variable “challenges” qui indique que, pour des mesures de sécurité, les éléments stockés ici devraient expirer au bout de 5 minutes (ce qui n’est pas en place dans ce mini projet).

WebAuthn - Mise en place d’une authentification WEB sans mot de passe

De manière générale et pour la suite des portions de codes, n’hésitez pas à vous rapprocher de la documentation de SimpleWebAuthn ainsi que celle sur W3C Recommandation sur le protocole WebAuthn pour comprendre en détail les paramètres utilisés. 

La première fonction de la classe va permettre la génération de l'option pour l'inscription :

WebAuthn - Mise en place d’une authentification WEB sans mot de passe

La seconde fonction va permettre de valider les informations d’inscription envoyées par le front (voir paragraphe suivant) :

WebAuthn - Mise en place d’une authentification WEB sans mot de passe

La troisième fonction va permettre la génération d’un challenge pour l’authentification :

WebAuthn - Mise en place d’une authentification WEB sans mot de passe

Notez que la variable “requestId” va nous permettre d’identifier le challenge à valider dans la fonction suivante.

Finalement, la dernière fonction va permettre de valider les informations d’authentification envoyées par le front, et donc de connecter l’utilisateur :

WebAuthn - Mise en place d’une authentification WEB sans mot de passe

Voilà ! Nous avons vu l’ensemble des éléments à mettre en place côté backend. Évidemment, dans une véritable application, certains éléments sont à améliorer et à adapter à votre style et éléments techniques comme votre base de données utilisée.

Frontend - ReactJs

Comme pour le back, veuillez commencer par générer un projet ReactJs vide (avec Vite ou Create React App par exemple) en vous basant sur la documentation officielle.
Ensuite, il nous faudra installer l’élément suivant :

WebAuthn - Mise en place d’une authentification WEB sans mot de passe

Nous allons ensuite nous concentrer uniquement sur le fichier “app.tsx”.

Nous aurons tout d’abord besoin des imports suivants :

WebAuthn - Mise en place d’une authentification WEB sans mot de passe

Ensuite, au tout début de la fonction “App” nous allons créer un state qui nous permettra d’afficher les messages de succès ou d’erreurs potentiel de nos différents appels API au back ou a WebAuthn :

WebAuthn - Mise en place d’une authentification WEB sans mot de passe

Passons maintenant au premier callback qui aura pour responsabilité de gérer l’inscription :

WebAuthn - Mise en place d’une authentification WEB sans mot de passe

Les grands principes de cette fonctions à comprendre sont les suivants :

  1. Appel à l’API de notre back sur “/api/biometric/register/option” afin de récupérer le challenge d’inscription.
  2. Appel à l’API WebAuthn du navigateur via la méthode “startRegistration” de la bibliothèque SimpleWebAuthn. C’est ici que le navigateur va inviter l’utilisateur à choisir quelle méthode d’authentification enregistrer.
  3. Appel à l’API de notre back sur “/api/biometric/register” en lui fournissant les différents éléments générés par le navigateur afin de persister la méthode de connexion pour l’utilisateur.

Vient ensuite le second callback responsable de la logique d’authentification :

WebAuthn - Mise en place d’une authentification WEB sans mot de passe

Le fonctionnement est très proche du callback précédent :

  1. Appel à l’API de notre back sur “/api/biometric/authentificate/option” afin de récupérer le challenge de connexion. A noter qu’ici on récupère également le “requestId” en plus du challenge. C’est cette variable qui nous permet de faire le lien entre la récupération du challenge et la validation de celui-ci (voir point 3).
  2. Appel à l’API WebAuthn du navigateur via la méthode “startAuthentification” de la bibliothèque SimpleWebAuthn. C’est ici que le navigateur va inviter l’utilisateur à choisir quelle méthode d’authentification utiliser.
  3. Appel à l’API de notre back sur “/api/biometric/authentificate” en lui fournissant les différents éléments générés par le navigateur et le “requestId” afin de valider la connexion de l’utilisateur.

Finalement, voici le rendu que nous voulons afficher sur le navigateur :

WebAuthn - Mise en place d’une authentification WEB sans mot de passe

Le premier paragraphe permet de montrer si le navigateur est compatible avec WebAuthn, ce qui peut être pratique pour afficher, ou non, les boutons d’interaction.

Le premier bouton permet de s’inscrire en tant que l’utilisateur “example”. Rappelez-vous, côté back, nous simulons le fait d’être connecté avec un utilisateur nommé “example”.

Le second bouton permet de déclencher l’authentification.

Les éléments affichés pour gérer la connexion / authentification via WebAuthn étant géré par le navigateur, ceux-ci sont différents d’un navigateur à l’autre. Nous vous invitons donc à essayer le code présenté pour observer tout ça par vous même. Bien-sûr la technologie étant standard, les moyens d’interactions restent les mêmes (à savoir la librairie SimpleWebAuthn pour nous).

Nous venons donc de voir comment implémenter de manière simple WebAuthn dans une application web. Vous êtes maintenant en mesure d’utiliser une authentification par empreinte digitale (par exemple) sur vos applications web.

Si vous désirez mettre en place ce type d’authentification moderne et sécurisé, n’hésitez pas à contacter Next Decision pour que nous puissions répondre à vos besoins métiers dans des interfaces dédiées innovantes.

 

Un besoin d'interfaces innovantes ? Next Decision se fera un plaisir de vous accompagner dans votre projet. Contactez-nous !