Présentation des optimisations, des requêtes d'origine associées et de la sérialisation JSON pour WebAuthn dans Chrome

Chrome 128 et 129 introduisent de nouvelles fonctionnalités intéressantes pour WebAuthn, l'API sous-jacente permettant de créer des systèmes d'authentification basés sur des clés d'accès.

  • Indices: les indices permettent aux parties de confiance (RP) de mieux contrôler l'interface utilisateur WebAuthn dans le navigateur. Ils sont particulièrement utiles pour les utilisateurs professionnels qui souhaitent utiliser des clés de sécurité.
  • Requêtes d'origines associées: avec les requêtes d'origine associées, les RP peuvent rendre des clés d'accès valides sur plusieurs domaines. Si vous possédez plusieurs sites, vous pouvez désormais autoriser vos utilisateurs à réutiliser leur clé d'accès sur l'ensemble de vos sites, ce qui élimine les frictions liées à la connexion.
  • Sérialisation JSON: les API de sérialisation JSON vous permettent de simplifier le code de l'interface d'une RP en encodant et en décodant les options et les identifiants transmis vers et depuis l'API WebAuthn.

Astuces

Avec hints, les tiers de confiance (RP) peuvent désormais spécifier des préférences d'UI pour la création d'une clé d'accès ou l'authentification avec une clé d'accès.

Auparavant, lorsqu'un RP souhaitait limiter l'authentificateur que l'utilisateur pouvait utiliser pour créer une clé d'accès ou pour s'authentifier, il pouvait utiliser authenticatorSelection.authenticatorAttachment pour spécifier "platform" ou "cross-platform". Ils limitent respectivement l'authentificateur à un authentificateur de plate-forme ou à un authentificateur en itinérance. Avec hints, cette spécification peut être plus flexible.

Le RP peut utiliser hints facultatif dans PublicKeyCredentialCreationOptions ou PublicKeyCredentialRequestOptions pour spécifier "security-key", "client-device" et "hybrid" dans un ordre de préférence dans un tableau.

Voici un exemple de requête de création d'identifiants qui privilégie les authentificateurs "cross-platform" avec "security-key" comme indice. Cela indique à Chrome d'afficher une UI axée sur les clés de sécurité pour les utilisateurs professionnels.

const credential = await navigator.credentials.create({
  publicKey: {
    challenge: *****,
    hints: ['security-key'],
    authenticatorSelection: {
      authenticatorAttachment: 'cross-platform'
    }
  }
});
En spécifiant "security-key" comme indice, le navigateur affiche une boîte de dialogue centrée sur la clé de sécurité.
En spécifiant "security-key" comme indice, le navigateur affiche une boîte de dialogue axée sur la clé de sécurité.

Lorsqu'un RP souhaite donner la priorité à un scénario de validation inter-appareils, il peut envoyer une requête d'authentification qui privilégie les authentificateurs "cross-platform" avec "hybrid" comme indice.

const credential = await navigator.credentials.create({
  publicKey: {
    challenge: *****,
    residentKey: true,
    hints: ['hybrid']
    authenticatorSelection: {
      authenticatorAttachment: 'cross-platform'
    }
  }
});
En spécifiant "hybrid" comme indice, le navigateur affiche une boîte de dialogue de connexion multi-appareil.
En spécifiant "hybrid" comme indice, le navigateur affiche une boîte de dialogue de connexion multi-appareil.

Avec les requêtes d'origine associées, les RP peuvent rendre les clés d'accès utilisables à partir de plusieurs domaines. La création d'une expérience de connexion centralisée et l'utilisation de protocoles de fédération restent la solution recommandée pour la plupart des sites. Toutefois, si vous possédez plusieurs domaines et que la fédération n'est pas possible, les origines associées peuvent être une solution.

Toutes les requêtes WebAuthn doivent spécifier un ID de tiers de confiance (ID RP), et toutes les clés d'accès sont associées à un seul ID RP. Traditionnellement, une origine ne pouvait spécifier qu'un ID de RP en fonction de son domaine. Dans ce cas, www.example.co.uk pouvait spécifier un ID de RP de example.co.uk, mais pas de example.com. Avec les requêtes d'origine associées, un ID de RP revendiqué peut être validé en récupérant un fichier JSON bien connu situé à /.well-known/webauthn à partir du domaine cible. Par conséquent, example.co.uk (et example.in, example.de, etc.) peuvent tous utiliser un ID de RP de example.com si example.com les spécifie au format suivant:

URL : https://example.com/.well-known/webauthn

{
  "origins": [
    "https://example.co.uk",
    "https://example.de",
    "https://example.sg",
    "https://example.net",
    "https://exampledelivery.com",
    "https://exampledelivery.co.uk",
    "https://exampledelivery.de",
    "https://exampledelivery.sg",
    "https://myexamplerewards.com",
    "https://examplecars.com"
  ]
}

Pour savoir comment configurer des requêtes d'origine associées, consultez Autoriser la réutilisation des clés d'accès sur vos sites avec des requêtes d'origine associées.

Sérialisation JSON

Les objets de requête et de réponse WebAuthn comportent plusieurs champs qui contiennent des données binaires brutes dans un ArrayBuffer, tels que l'ID d'identification, l'ID utilisateur ou la question d'authentification. Si un site Web souhaite utiliser JSON pour échanger ces données avec son serveur, les données binaires doivent d'abord être encodées, par exemple avec Base64URL. Cela ajoute une complexité inutile pour les développeurs qui souhaitent commencer à utiliser des clés d'accès sur leurs sites Web.

WebAuthn propose désormais des API pour analyser les objets de requête WebAuthn PublicKeyCredentialCreationOptions et PublicKeyCredentialRequestOptions directement à partir de JSON, et pour sérialiser la réponse PublicKeyCredential directement en JSON. Tous les champs de valeur ArrayBuffer qui contiennent des données binaires brutes sont automatiquement convertis à partir de ou vers leurs valeurs encodées en Base64URL. Ces API sont disponibles à partir de Chrome 129.

Avant de créer une clé d'accès, récupérez un objet PublicKeyCredentialCreationOptions encodé en JSON sur le serveur et décodez-le à l'aide de PublicKeyCredential.parseCreationOptionsFromJSON().

Navigateurs pris en charge

  • Chrome: 129
  • Edge : 129.
  • Firefox : 119.
  • Safari : non compatible.

Source

export async function registerCredential() {

  // Fetch encoded `PublicKeyCredentialCreationOptions`
  // and JSON decode it.
  const options = await fetch('/auth/registerRequest').json();

  // Decode `PublicKeyCredentialCreationOptions` JSON object
  const decodedOptions = PublicKeyCredential.parseCreationOptionsFromJSON(options);  

  // Invoke the WebAuthn create() function.
  const cred = await navigator.credentials.create({
    publicKey: decodedOptions,
  });
  ...

Après avoir créé une clé d'accès, encodez l'identifiant obtenu à l'aide de toJSON() afin qu'il puisse être envoyé au serveur.

Navigateurs pris en charge

  • Chrome : 129.
  • Edge: 129
  • Firefox : 119.
  • Safari: non compatible.

Source

  ...
  const cred = await navigator.credentials.create({
    publicKey: options,
  });

  // Encode the credential to JSON and stringify
  const credential = JSON.stringify(cred.toJSON());

  // Send the encoded credential to the server
  await fetch('/auth/registerResponse', credential);
  ...

Avant de vous authentifier avec une clé d'accès, extrayez un PublicKeyRequestCreationOptions encodé en JSON sur le serveur et décodez-le à l'aide de PublicKeyCredential.parseRequestOptionsFromJSON().

Navigateurs pris en charge

  • Chrome : 129.
  • Edge : 129.
  • Firefox : 119.
  • Safari : non compatible.

Source

export async function authenticate() {

  // Fetch encoded `PublicKeyCredentialRequestOptions`
  // and JSON decode it.
  const options = await fetch('/auth/signinRequest').json();

  // Decode `PublicKeyCredentialRequestOptions` JSON object
  const decodedOptions = PublicKeyCredential.parseRequestOptionsFromJSON(options);

  // Invoke the WebAuthn get() function.
  const cred = await navigator.credentials.get({
    publicKey: options
  });
  ...

Après vous être authentifié avec une clé d'accès, encodez l'identifiant obtenu à l'aide de la méthode toJSON() afin qu'il puisse être envoyé au serveur.

Navigateurs pris en charge

  • Chrome: 129
  • Edge : 129.
  • Firefox : 119.
  • Safari : non compatible.

Source

  ...
  const cred = await navigator.credentials.get({
    publicKey: options
  });

  // Encode the credential to JSON and stringify
  const credential = JSON.stringify(cred.toJSON());

  // Send the encoded credential to the server
  await fetch(`/auth/signinResponse`, credential);
  ...

En savoir plus

Pour en savoir plus sur WebAuthn et les clés d'accès, consultez les ressources suivantes: