Cas d'utilisation des clés d'accès
Cette rubrique décrit certains cas d’usage pour les clés secrètes.
Cas d’usage 1 : démarrage
Démarrage d’un compte sur le web.
1.1 : Authentification de l’utilisateur
Cette section s’applique lorsque la partie de confiance (RP) ne sait pas encore qui contrôle l’appareil client. Il n’existe aucun artefact de navigateur disponible pour le fournisseur de ressources (par exemple, un cookie ou un ID d’informations d’identification dans le stockage local), bien que pour le moment, nous supposons que l’utilisateur dispose d’un compte existant avec le fournisseur de ressources.
Pour démarrer un compte, servez-vous de la page de connexion de l’utilisateur.
Commencez par demander à l’utilisateur l’identificateur de son compte ; généralement un nom d’utilisateur ou une adresse e-mail.
Pour prendre en charge l’interface utilisateur de remplissage automatique pour les clés secrètes, veillez à :
- Ajoutez la
username
valeur àwebauthn
toutes les annotations de saisie semi-automatique existantes dans le champ d’entrée du nom d’utilisateur .
<div>
<label for="username">Username:</label>
<input name="username" id="loginform.username"
autocomplete="username webauthn">
</div>
- Lors du chargement de page, utilisez une
if
instruction pour vérifier si l’interface utilisateur de remplissage automatique (médiation conditionnelle) est disponible, puis appeleznavigator.credentials.get()
avecmediation: "conditional"
etuserVerification: "preferred"
.
<script>
(async () => {
if (
typeof window.PublicKeyCredential !== 'undefined'
&& typeof window.PublicKeyCredential.isConditionalMediationAvailable === 'function'
) {
const available = await PublicKeyCredential.isConditionalMediationAvailable();
if (available) {
try {
// Retrieve authentication options for `navigator.credentials.get()`
// from your server.
const authOptions = await getAuthenticationOptions();
// This call to `navigator.credentials.get()` is "set and forget."
// The Promise will resolve only if the user successfully interacts
// with the browser's autofill UI to select a passkey.
const webAuthnResponse = await navigator.credentials.get({
mediation: "conditional",
publicKey: {
...authOptions,
// See note about userVerification below.
userVerification: "preferred",
}
});
// Send the response to your server for verification, and
// authenticate the user if the response is valid.
await verifyAutoFillResponse(webAuthnResponse);
} catch (err) {
console.error('Error with conditional UI:', err);
}
}
}
})();
</script>
Les éléments ci-dessus entraînent l’erreur suivante :
- Récupérez les options d’authentification de votre serveur. Retournez au moins une requête d’authentification aléatoire
challenge
etrpId
à associer à cette demande d’authentification. - Lorsque l’utilisateur interagit avec votre champ de nom d’utilisateur , le navigateur et la plateforme vérifient si une clé secrète existe (dans l’authentificateur de plateforme) qui peut être utilisée avec la partie de confiance.
- Si c’est le cas, la clé secrète sera présentée à l’utilisateur comme option à choisir (ainsi que d’autres informations d’identification qui peuvent être renseignées automatiquement, telles que les noms d’utilisateur stockés dans le gestionnaire de mots de passe du navigateur). Le navigateur/la plateforme peut afficher une interface utilisateur similaire à celle indiquée ci-dessous. Bien que l’apparence exacte varie d’une plateforme ou d’un facteur de forme à une autre :
- Si l’utilisateur sélectionne la clé secrète, l’interface utilisateur de la plateforme guide l’utilisateur par le biais d’une vérification utilisateur (souvent biométrique).
- Si l’utilisateur réussit la vérification de l’utilisateur, l’appel
navigator.credentials.get()
réussit et retourne une réponse WebAuthn. - Si l’utilisateur sélectionne des informations d’identification autres qu’une clé secrète, le navigateur/la plateforme choisit une autre action appropriée (par exemple, le remplissage automatique du nom d’utilisateur) et l’appel
navigator.credentials.get()
ne se résout pas. - Si l’utilisateur sélectionne l’option « Passkey from another device » (le texte exact varie légèrement par plateforme), le navigateur/plateforme guide l’utilisateur à l’aide d’une clé de sécurité FIDO2 ou du flux DDA (Cross-Device Authentication) pour utiliser une clé secrète à partir de son smartphone ou tablette pour fournir une réponse WebAuthn à l’appel
navigator.credentials.get()
. - Envoyez la réponse WebAuthn à votre serveur pour la vérification et des vérifications de sécurité supplémentaires. Si toutes les vérifications réussissent, commencez une session authentifiée pour cet utilisateur.
C’est pourquoi il s’agit du mode d’interface utilisateur conditionnelle (ou, plus souvent, de l’interface utilisateur de remplissage automatique) de WebAuthn, l’interface utilisateur d’authentificateur de plateforme qui guide l’utilisateur via la vérification ou l’utilisation de son téléphone, s’affiche uniquement si l’utilisateur a une clé secrète sur cet appareil (ou choisit l’option « un autre appareil »).
Comme vous pouvez le voir, dans ce mode, l’appel navigator.credentials.get()
réussit ou n’est pas parce qu’il ne se résout jamais. Si elle réussit, le résultat de l’appel révèle à la fois un ID d’utilisateur et une assertion WebAuthn signée, que la partie de confiance (RP) utilisera pour authentifier l’utilisateur.
Si l’appel ne réussit pas, vous devez effectuer une authentification utilisateur héritée . Vous obtiendrez un nom d’utilisateur à partir de cette première page et, dans les pages suivantes, vous répondez ensuite aux défis de connexion appropriés (tels que les mots de passe, la réponse aux défis SMS, etc.) à l’utilisateur. Ceux-ci peuvent inclure des étapes de récupération de compte si l’utilisateur a oublié son mot de passe ou n’est pas en mesure de passer les défis de connexion standard. Une fois que l’utilisateur a réussi tous les défis de connexion, il est considéré comme authentifié et connecté.
Lorsque l’utilisateur n’a pas encore de compte avec la partie de confiance (RP), vous devez généralement donner à l’utilisateur l’option sur la page de connexion pour créer un compte. Si l’utilisateur choisit cette option, vous collecterez les informations nécessaires pour ouvrir un nouveau compte. S’ils ouvrent correctement un nouveau compte, ils sont également considérés comme authentifiés et connectés.
Une fois que l’utilisateur est connecté, il peut être temps de configurer une nouvelle clé secrète pour eux. Procédez ainsi pour l’un des cas suivants :
- L’utilisateur a démarré son compte sur l’appareil en passant des défis de connexion sans clé secrète (par exemple, à l’aide d’un mot de passe).
- L’utilisateur vient de créer un compte à la partie de confiance (RP), et il est considéré comme connecté en raison de cela.
- L’utilisateur utilise une clé secrète, mais il utilise un appareil différent de celui qu’il utilise actuellement (en sélectionnant « autre appareil » illustré dans l’exemple ci-dessus). Cela peut être confirmé en inspectant l’attribut authenticatorAttachment dans l’objet PublicKeyCredential retourné.
1.2 : Authentification inter-appareils
Si l’utilisateur a utilisé une clé secrète à partir d’un autre appareil (par exemple, un téléphone, une tablette ou une clé de sécurité FIDO2), la propriété authenticatorAttachment dans la réponse d’authentification (getAssertion) aura la valeur cross-platform
.
Dans ce scénario, offrez à l’utilisateur le choix de créer une clé secrète sur son appareil local. Cela entraînera une expérience utilisateur plus transparente à l’avenir, car l’utilisateur ne sera pas tenu d’utiliser son autre appareil.
1.3 : Note sur la vérification des utilisateurs
Ces instructions définissent userVerification preferred
sur , ce qui signifie que la vérification de l’utilisateur sera tentée lorsque cela est possible.
Certains appareils, tels que les ordinateurs de bureau et les ordinateurs portables plus anciens, peuvent ne pas avoir de capteurs biométriques. Sur ces appareils, si userVerification est défini required
sur , l’utilisateur peut être invité à entrer son mot de passe de connexion système pour chaque connexion à l’aide d’une clé secrète. Et cela peut être frustrant pour eux.
Lorsqu’il preferred
est utilisé, certains authentificateurs de plateforme nécessitent toujours un contrôle de vérification utilisateur lorsque l’appareil dispose de capteurs biométriques, mais peut ignorer la vérification des utilisateurs sur les appareils sans eux.
Le résultat de la vérification utilisateur (transmis dans les indicateurs de données d’authentificateur) reflète le résultat de vérification utilisateur réel et doit toujours être validé en fonction de vos besoins sur le serveur.
1.4 : Choisir l’utilisateur pour passer des clés
Tout d’abord, vérifiez que l’utilisateur est suffisamment authentifié à l’aide d’autres méthodes de connexion, notamment l’authentification multifacteur.
Ensuite, assurez-vous que la liste déroulante appareil et système d’exploitation de l’utilisateur prend en charge les clés secrètes en appelant :
PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable()
Si les clés secrètes sont prises en charge, cela retourne true
. S’ils ne sont pas pris en charge, il retourne false
, et vous devez abandonner le flux d’inscription de clé secrète.
Servez un opt-in ou « upsell » modal/interstitial ou page à l’utilisateur leur offrant de créer une clé secrète :
Conseil
Pour vous assurer que l’utilisateur donne un consentement éclairé, envisagez d’afficher (ou de lier à) des descriptions plus longues expliquant que tous les utilisateurs capables de déverrouiller l’appareil actuel pourront accéder au compte à la partie de confiance (RP).
Si l’utilisateur consent, appelez navigator.credentials.create()
avec les options indiquées dans l’exemple ci-dessous :
navigator.credentials.create({
publicKey: {
rp: {
// User-friendly name of your service.
name: "Passkeys Developer",
// Relying party (RP) identifier (hostname/FQDN).
id: passkeys.contoso"
},
user: {
// Persistent, unique identifier for the user account in your backend.
id: Uint8Array.from("0525bc79-5a63-4e47-b7d1-597e25f5caba", c => c.charCodeAt(0)),
// User-friendly identifier often displayed to the user (for example, email address).
name: "amanda@contoso.com",
// Human-readable display name, sometimes displayed by the client.
displayName: "Amanda Brady"
},
// The challenge is a buffer of cryptographically random bytes generated on your backend,
// and should be tightly bound to the current user session.
challenge: Uint8Array.from("XZJscsUqtBH7ZB90t2g0EbZTZYlbSRK6lq7zlN2lJKuoYMnp7Qo2OLzD7xawL3s", c => c.charCodeAt(0)),
pubKeyCredParams: [
// An array of objects describing what public key types are acceptable to a server.
{
"type": "public-key",
"alg": -7 // EC P256
},
{
"type": "public-key",
"alg": -257 // RSA
}
],
excludeCredentials: [
// Array of credential IDs for existing passkeys tied to the user account.
// This avoids creating a new passkey in an authenticator that already has
// a passkey tied to the user account.
{
// Example only.
type: "public-key",
id: new Uint8Array([21, 31, 56, ...]).buffer
},
{
// Example only.
type: "public-key",
id: new Uint8Array([21, 31, 56, ...]).buffer
}
],
authenticatorSelection: {
// Tells the authenticator to create a passkey.
residentKey: "required",
// Tells the client/authenticator to request user verification where possible;
// for example, a biometric or a device PIN.
userVerification: "preferred"
},
"extensions": {
// Returns details about the passkey.
"credProps": true
}
}
})
Remarque
Nous vous recommandons que la plupart des parties de confiance ne spécifient pas le paramètre attestation
de transmission d’attestation (par défaut, aucun) ou utilisent explicitement la valeur indirect
. Cela garantit l’expérience utilisateur la plus simplifiée (les plateformes sont susceptibles d’obtenir le consentement de l’utilisateur pour d’autres types de transmissions d’attestation, ce qui entraîne probablement une plus grande proportion de créations d’informations d’identification infructueuses en raison de l’annulation de la création par les utilisateurs).
Lorsque l’appel WebAuthn est résolu, envoyez la réponse à votre serveur et associez la clé publique retournée et l’ID d’informations d’identification au compte d’utilisateur précédemment authentifié.
Cas d’usage 2 : Réauthentication
L’utilisation de clés secrètes pour une réauthentification peut être nécessaire pour l’une des raisons suivantes :
- L’utilisateur s’est déconnecté et souhaite maintenant se reconnecter.
- La session utilisateur a expiré en raison de l’inactivité et l’utilisateur souhaite se reconnecter.
- L’utilisateur est sur le point d’effectuer une action sensible et doit confirmer à nouveau le contrôle sur la session utilisateur.
Pour réauthentifier l’utilisateur dans chacune de ces situations, vous allez utiliser des clés secrètes que vous avez configurées dans le cas d’usage précédent. L’appel d’API WebAuthn est le même dans les trois cas, mais le traitement de l’interface utilisateur que vous fournissez est légèrement différent. Étant donné que le compte particulier est spécifié par vous, la plateforme n’invite pas l’utilisateur à sélectionner un autre compte sur votre service.
2.1 : Actions sensibles
Examinons d’abord l’interface utilisateur pour la troisième raison : quand il est temps de réauthentifier pour une action sensible, vérifiez si vous avez un ID d’informations d’identification pour au moins une clé secrète pour l’utilisateur.
Si aucun ID d’informations d’identification de ce type n’est disponible, servez un défi de connexion traditionnel adapté à la réauthentification, par exemple :
Conseil
Nous vous recommandons que sur cette page de défi de connexion, les utilisateurs ne peuvent pas modifier leur identificateur de compte. En outre, le défi de connexion doit être quelque chose qu’un utilisateur non autorisé de l’appareil ne peut pas passer.
Si, d’autre part, vous trouvez au moins un ID d’informations d’identification de clé secrète pour l’utilisateur, vous pouvez utiliser des clés secrètes pour la réauthentification :
Lorsque l’utilisateur est prêt (dans l’exemple ci-dessus, lorsqu’il clique sur le bouton « Go »), appelez navigator.credentials.get()
, en passant tous les ID d’informations d’identification de clé secrète de l’utilisateur :
navigator.credentials.get({
publicKey: {
challenge: ...,
rpId: ...,
allowCredentials: [{
type: "public-key",
id: new UInt8Array([21, 31, 56, ...]).buffer,
}, {
type: "public-key",
id: new UInt8Array([21, 31, 56, ...]).buffer,
}, {
...
}],
// see note below
userVerification: "preferred",
}
});
Remarque
Veillez à lire les instructions relatives à userVerification à partir du cas d’usage précédent.
Si l’utilisateur clique plutôt sur « Essayer une autre façon », vous devez leur proposer d’autres méthodes de connexion (mot de passe, etc.) pour les réauthentifier (en supposant que l’utilisateur dispose de ces autres méthodes de connexion disponibles).
2.2 : Sessions expirées et déconnexion
Nous allons maintenant examiner le cas où la réauthentification est déclenchée, car l’utilisateur s’est déconnecté, ou la partie de confiance (RP) a expiré la session de l’utilisateur. Pour faciliter cela, le fournisseur de ressources doit conserver une forme d’état de session utilisateur lui rappelant le compte qui a été précédemment connecté, même lorsqu’il considère que l’utilisateur est déconnecté (ce qui peut être obtenu à l’aide d’artefacts de navigateur tels que les cookies ou le stockage local).
Remarque
Une partie de confiance peut choisir de traiter la déconnexion comme une action complète, et ainsi supprimer toutes les références à l’identité de l’utilisateur. Un tel fournisseur de ressources doit traiter une connexion ultérieure comme un démarrage de compte et répéter les étapes expliquées précédemment.
Vous, en tant que rp, peut ensuite servir une page de connexion comme suit :
Si l’utilisateur clique sur « Utiliser un autre compte », vous devez entrer un flux de démarrage de compte, comme expliqué pour le cas d’usage précédent, en répétant les étapes là-bas, où la plateforme permet à l’utilisateur de sélectionner le compte qu’il souhaite utiliser.
Remarque
Dans ce cas, vous devez également donner à l’utilisateur la possibilité de supprimer complètement le compte suggéré d’être répertorié sur la page de connexion.
Toutefois, si l’utilisateur clique sur le bouton « Se connecter en tant que », vérifiez si vous avez au moins un ID d’informations d’identification de clé secrète associé à l’utilisateur. Si aucun ID d’informations d’identification n’est disponible, servez un défi de connexion traditionnel adapté à la réauthentification, par exemple :
Si, d’autre part, vous trouvez au moins un ID d’informations d’identification de clé secrète pour l’utilisateur, vous pouvez utiliser des clés secrètes pour la réauthentification :
Lorsque l’utilisateur est prêt (dans l’exemple ci-dessus, lorsqu’il clique sur le bouton « Go »), appelez navigator.credentials.get()
, exactement comme indiqué (autrement dit, en transmettant tous les ID d’informations d’identification de passe de l’utilisateur).
Si l’utilisateur clique plutôt sur « Essayer une autre façon », vous devez leur proposer d’autres méthodes de connexion (mot de passe, etc.) pour les réauthentifier (en supposant que l’utilisateur dispose de ces autres méthodes de connexion disponibles).
Étapes suivantes
Ensuite, consultez Outils et bibliothèques pour les clés secrètes.
Plus d’informations
- Introduction aux clés secrètes
- Passkeys.dev
- Prise en main de votre parcours sans mot de passe sur le site web FIDO Alliance
Windows developer