FIDO-Anmeldedaten wie Passkeys sollen Passwörter ersetzen, aber die meisten davon können Nutzer auch von der Eingabe eines Nutzernamens befreien. So können sich Nutzer authentifizieren, indem sie ein Konto aus einer Liste der Passkeys auswählen, die sie für die aktuelle Website haben.
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.
vertrauende Seiten (Relying Parties, RPs) können Anmeldedaten verwenden, die sich ermitteln lassen, indem sie allowCredentials
während der Passkey-Authentifizierung weglassen. In diesen Fällen zeigt der Browser oder das System dem Nutzer eine Liste der verfügbaren Passkeys an, die anhand der Property user.name
identifiziert werden, die 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 anstelle eines eingegebenen Nutzernamens abzurufen.
Benutzeroberflächen für die Kontoauswahl, wie die oben beschriebenen, zeigen nie nicht auffindbare Anmeldedaten an.
requireResidentKey
und residentKey
Wenn Sie einen Passkey erstellen möchten, geben Sie authenticatorSelection.residentKey
und authenticatorSelection.requireResidentKey
in 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 von anderen gefunden werden können. Kann die Datei nicht erstellt werden, wirdNotSupportedError
zurückgegeben.'preferred'
: Der RP bevorzugt das Erstellen von Anmeldedaten, die sich finden lassen, akzeptiert aber auch Anmeldedaten, die nicht auffindbar sind.'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. Legen Sie diesen Wert auf
true
fest, wennresidentKey
gleich'required'
ist, andernfalls auffalse
.
allowCredentials
RPs können allowCredentials
auf navigator.credentials.get()
verwenden, um die Passkey-Authentifizierung zu steuern. Es gibt in der Regel drei Arten der Passkey-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 haben. Wenn ein Nutzer keine lokalen Passkeys hat, wird das modale Dialogfeld trotzdem angezeigt und der Nutzer wird aufgefordert, einen Passkey von einem anderen Gerät vorzulegen. 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 die RP sich in einer Migration befindet und Passwörter und Passkeys gemeinsam verwendet werden.
Um diese Nutzererfahrung zu erzielen, müssen Sie nicht nur ein leeres Array an die Property allowCredentials
übergeben oder den Parameter weglassen, sondern auch mediation: 'conditional'
für navigator.credentials.get()
angeben und ein HTML-username
-Eingabefeld mit autocomplete="username webauthn"
oder ein password
-Eingabefeld mit autocomplete="password webauthn"
annotieren.
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" ...>
Wie Sie diese Nutzererfahrung gestalten, erfahren Sie unter Über die Formularautofill mit einem Passkey anmelden sowie im Codelab Passkeys mit Formularautofill in einer Webanwendung 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 enthält 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 Anmeldedaten, die für andere sichtbar sind, wird die Anmeldung mit Passkeys viel nutzerfreundlicher, da die Eingabe eines Nutzernamens übersprungen werden kann. Mit der Kombination aus residentKey
, requireResidentKey
und allowCredentials
können RPs Anmeldevorgänge ermöglichen, die:
- Eine modale Kontoauswahl anzeigen.
- Autofill für Passkey-Formular anzeigen
- 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.