FIDO-Anmeldedaten wie Passkeys sollen Passwörter ersetzen, aber die meisten davon können Nutzer auch von der Eingabe eines Nutzernamens befreien. Damit können sich Nutzer authentifizieren, indem sie ein Konto aus einer Liste von Passkeys für die aktuelle Website auswählen.
Frühere Versionen von Sicherheitsschlüsseln wurden als Methoden für die Bestätigung in zwei Schritten entwickelt und erforderten die IDs potenzieller Anmeldedaten, also die Eingabe eines Nutzernamens. Anmeldedaten, die ein Sicherheitsschlüssel finden kann, ohne ihre IDs zu kennen, werden als „findbare Anmeldedaten“ bezeichnet. Die meisten heute erstellten FIDO-Anmeldedaten sind auffindbare Anmeldedaten, insbesondere Passkeys, die in einem Passwortmanager oder auf einem modernen Sicherheitsschlüssel gespeichert sind.
Damit Ihre Anmeldedaten als Passkeys (erfindbare Anmeldedaten) erstellt werden, geben Sie beim Erstellen der Anmeldedaten residentKey
und requireResidentKey
an.
Abhängige Parteien können auffindbare Anmeldedaten verwenden, indem sie allowCredentials
bei der Passkey-Authentifizierung auslassen. In diesen Fällen zeigt der Browser oder System dem Nutzer eine Liste der verfügbaren Passkeys an, die durch das Attribut user.name
identifiziert werden, das bei der Erstellung festgelegt wurde. Wenn der Nutzer eine Option auswählt, wird der user.id
-Wert in die resultierende Signatur eingeschlossen. Der Server kann dann diese oder die zurückgegebene Anmeldedaten-ID verwenden, um das Konto abzurufen, anstatt einen eingegebenen Nutzernamen zu verwenden.
Benutzeroberflächen für die Kontoauswahl, wie die oben beschriebenen, zeigen niemals nicht auffindbare Anmeldedaten an.
requireResidentKey
und residentKey
Wenn Sie einen Passkey erstellen möchten, geben Sie authenticatorSelection.residentKey
und authenticatorSelection.requireResidentKey
unter navigator.credentials.create()
mit den folgenden Werten an.
async function register () {
// ...
const publicKeyCredentialCreationOptions = {
// ...
authenticatorSelection: {
authenticatorAttachment: 'platform',
residentKey: 'required',
requireResidentKey: true,
}
};
const credential = await navigator.credentials.create({
publicKey: publicKeyCredentialCreationOptions
});
// This does not run until the user selects a passkey.
const credential = {};
credential.id = cred.id;
credential.rawId = cred.id; // Pass a Base64URL encoded ID string.
credential.type = cred.type;
// ...
}
residentKey
:
'required'
: Es müssen Anmeldedaten erstellt werden, die gefunden werden können. Wenn die Datei nicht erstellt werden kann, wirdNotSupportedError
zurückgegeben.'preferred'
: Die RP bevorzugt die Erstellung erkennbarer Anmeldedaten, akzeptiert aber nicht auffindbare Anmeldedaten.'discouraged'
: Der RP bevorzugt die Erstellung nicht auffindbarer Anmeldedaten, akzeptiert aber auch solche, die auffindbar sind.
requireResidentKey
:
- Diese Eigenschaft wird aus Gründen der Abwärtskompatibilität aus WebAuthn Level 1 übernommen, einer älteren Version der Spezifikation. Wird auf
true
gesetzt, wennresidentKey
gleich'required'
ist, andernfalls auffalse
.
allowCredentials
RPs können allowCredentials
auf navigator.credentials.get()
verwenden, um die Passkey-Authentifizierung zu steuern. In der Regel gibt es drei Arten der Passkey-Authentifizierung:
- Modales Fenster für die Kontoauswahl anzeigen
- Autofill für Passkey-Formular anzeigen
- Erneute Authentifizierung
Modale Kontoauswahl anzeigen
Bei Anmeldedaten, die für die Suche sichtbar sind, können RPs eine modale Kontoauswahl anzeigen, über die der Nutzer ein Konto auswählen kann, mit dem er sich anmelden möchte, gefolgt von der Nutzerbestätigung. Dies eignet sich für den Passkey-Authentifizierungsablauf, der durch Drücken einer Schaltfläche für die Passkey-Authentifizierung gestartet wird.
Um diese Funktion zu aktivieren, lassen Sie den Parameter allowCredentials
in navigator.credentials.get()
aus oder übergeben Sie ein leeres Array.
async function authenticate() {
// ...
const publicKeyCredentialRequestOptions = {
// Server generated challenge:
challenge: ****,
// The same RP ID as used during registration:
rpId: 'example.com',
// You can omit `allowCredentials` as well:
allowCredentials: []
};
const credential = await navigator.credentials.get({
publicKey: publicKeyCredentialRequestOptions,
signal: abortController.signal
});
// This does not run until the user selects a passkey.
const credential = {};
credential.id = cred.id;
credential.rawId = cred.id; // Pass a Base64URL encoded ID string.
credential.type = cred.type;
// ...
}
Autofill für Passkey-Formular anzeigen
Die oben beschriebene modale Kontoauswahl funktioniert gut, wenn die meisten Nutzer Passkeys verwenden und diese auf dem lokalen Gerät verfügbar sind. Bei Nutzern, die keine lokalen Passkeys haben, wird das modale Dialogfeld weiterhin angezeigt und es wird ihnen angeboten, einen Passkey von einem anderen Gerät zu verwenden. Während Sie Ihre Nutzer auf Passkeys umstellen, sollten Sie diese Benutzeroberfläche für Nutzer vermeiden, die noch keinen Passkey eingerichtet haben.
Stattdessen kann die Auswahl eines Passkeys in Autofill-Aufforderungen für die Felder in einem herkömmlichen Anmeldeformular zusammen mit gespeicherten Nutzernamen und Passwörtern eingebunden werden. So kann ein Nutzer mit Passkeys das Anmeldeformular ausfüllen, indem er seinen Passkey auswählt. Nutzer mit gespeicherten Nutzernamen/Passwort-Paaren können diese auswählen und Nutzer, die weder einen Passkey noch einen Nutzernamen und ein Passwort haben, können diese weiterhin eingeben.
Diese Nutzererfahrung ist ideal, wenn das RP migriert wird und sowohl Passwörter als auch Passkeys verwendet wird.
Zusätzlich zum Übergeben eines leeren Arrays an die Eigenschaft allowCredentials
oder ohne den Parameter geben Sie mediation: 'conditional'
für navigator.credentials.get()
an und vermerken ein HTML-username
-Eingabefeld mit autocomplete="username webauthn"
oder ein password
-Eingabefeld mit autocomplete="password webauthn"
.
Durch den Aufruf von navigator.credentials.get()
wird keine Benutzeroberfläche angezeigt. Wenn der Nutzer das beschriftete Eingabefeld jedoch fokussiert, werden alle verfügbaren Passkeys in den Autofill-Optionen aufgeführt. Wenn der Nutzer eine auswählt, wird die normale Bestätigung der Geräteentsperrung durchgeführt. Erst dann wird das von .get()
zurückgegebene Versprechen mit einem Ergebnis aufgelöst. Wenn der Nutzer keinen Passkey auswählt, wird die Zusicherung nie erfüllt.
async function authenticate() {
// ...
const publicKeyCredentialRequestOptions = {
// Server generated challenge:
challenge: ****,
// The same RP ID as used during registration:
rpId: 'example.com',
// You can omit `allowCredentials` as well:
allowCredentials: []
};
const cred = await navigator.credentials.get({
publicKey: publicKeyCredentialRequestOptions,
signal: abortController.signal,
// Specify 'conditional' to activate conditional UI
mediation: 'conditional'
});
// This does not run until the user selects a passkey.
const credential = {};
credential.id = cred.id;
credential.rawId = cred.id; // Pass a Base64URL encoded ID string.
credential.type = cred.type;
// ...
}
<input type="text" name="username" autocomplete="username webauthn" ...>
Weitere Informationen dazu finden Sie unter Mit einem Passkey über Autofill anmelden und im Codelab Passkeys mit Autofill in Web-Apps implementieren.
Erneute Authentifizierung
In einigen Fällen, z. B. bei der Verwendung von Passkeys für die erneute Authentifizierung, ist die Kennung des Nutzers bereits bekannt. In diesem Fall möchten wir einen Passkey verwenden, ohne dass der Browser oder das Betriebssystem eine Kontoauswahl anzeigt. Dazu übergeben Sie im Parameter allowCredentials
eine Liste mit Anmeldedaten-IDs.
Wenn in diesem Fall eine der angegebenen Anmeldedaten lokal verfügbar ist, wird der Nutzer sofort zum Entsperren des Geräts aufgefordert. Andernfalls wird der Nutzer aufgefordert, ein anderes Gerät (ein Smartphone oder einen Sicherheitsschlüssel) vorzulegen, auf dem gültige Anmeldedaten gespeichert sind.
Geben Sie dazu eine Liste mit Anmeldedaten-IDs für den Nutzer an, der sich anmeldet. Der RP sollte sie abfragen können, da der Nutzer bereits bekannt ist. Geben Sie Anmeldedaten-IDs als PublicKeyCredentialDescriptor
-Objekte in der Property allowCredentials
in navigator.credentials.get()
an.
async function authenticate() {
// ...
const publicKeyCredentialRequestOptions = {
// Server generated challenge:
challenge: ****,
// The same RP ID as used during registration:
rpId: 'example.com',
// Provide a list of PublicKeyCredentialDescriptors:
allowCredentials: [{
id: ****,
type: 'public-key',
transports: [
'internal',
'hybrid'
]
}, {
id: ****,
type: 'public-key',
transports: [
'internal',
'hybrid'
]
}, ...]
};
const credential = await navigator.credentials.get({
publicKey: publicKeyCredentialRequestOptions,
signal: abortController.signal
});
// This does not run until the user selects a passkey.
const credential = {};
credential.id = cred.id;
credential.rawId = cred.id; // Pass a Base64URL encoded ID string.
credential.type = cred.type;
// ...
}
Ein PublicKeyCredentialDescriptor
-Objekt besteht aus:
id
: Eine ID der Anmeldedaten für den öffentlichen Schlüssel, die der RP bei der Passkey-Registrierung erhalten hat.type
: Dieses Feld ist normalerweise'public-key'
.transports
: Ein Hinweis auf die Übertragungsmethoden, die vom Gerät mit diesen Anmeldedaten unterstützt werden. Wird von Browsern verwendet, um die Benutzeroberfläche zu optimieren, auf der der Nutzer aufgefordert wird, ein externes Gerät vorzulegen. Diese Liste, sofern vorhanden, sollte das Ergebnis des Aufrufs vongetTransports()
bei der Registrierung der einzelnen Anmeldedaten enthalten.
Zusammenfassung
Durch auffindbare Anmeldedaten ist die Anmeldung mit Passkeys noch benutzerfreundlicher, da die Eingabe eines Nutzernamens übersprungen werden muss. Mit der Kombination aus residentKey
, requireResidentKey
und allowCredentials
können RPs Anmeldevorgänge ermöglichen, die:
- Modales Konto zur Kontoauswahl anzeigen
- Passkey-Formular automatisch ausfüllen lassen.
- Erneute Authentifizierung.
Verwenden Sie Anmeldedaten, die für andere sichtbar sind, mit Bedacht. So können Sie eine ausgefeilte Passkey-Anmeldung entwerfen, die für Nutzer nahtlos ist und mit der sie eher interagieren.