FIDO-Anmeldedaten wie Passkeys sollen zwar Passwörter ersetzen, in den meisten Fällen können sie dem Nutzer aber auch die Eingabe eines Nutzernamens ersparen. So können sich Nutzer authentifizieren, indem sie ein Konto aus einer Liste von Passkeys auswählen, die sie für die aktuelle Website haben.
Ältere Versionen von Sicherheitsschlüsseln waren als 2-Faktor-Authentifizierungsmethoden konzipiert und erforderten die IDs potenzieller Anmeldedaten, sodass ein Nutzername eingegeben werden musste. Anmeldedaten, die ein Sicherheitsschlüssel ohne Kenntnis ihrer IDs finden kann, werden als _auffindbare 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.
Wenn Sie sicherstellen möchten, dass Ihre Anmeldedaten als Passkeys (auffindbare Anmeldedaten) erstellt werden, geben Sie residentKey und requireResidentKey beim Erstellen der Anmeldedaten an.
Vertrauende Parteien können auffindbare Anmeldedaten verwenden, indem sie
allowCredentials bei der Passkey-Authentifizierung weglassen. In diesen Fällen zeigt der Browser oder das System dem Nutzer eine Liste der verfügbaren Passkeys an, die durch das bei der Erstellung festgelegte Attribut user.name identifiziert werden. Wenn der Nutzer einen Passkey auswählt, wird der Wert user.id in die resultierende Signatur aufgenommen. Der Server kann dann anstelle eines eingegebenen Nutzernamens diesen Wert oder die zurückgegebene Anmeldedaten-ID verwenden, um das Konto zu suchen.
Auf Benutzeroberflächen zur Kontoauswahl, wie den oben beschriebenen, werden niemals nicht auffindbare Anmeldedaten angezeigt.
requireResidentKey und residentKey
Wenn Sie einen Passkey erstellen möchten, geben Sie für navigator.credentials.create() authenticatorSelection.residentKey und authenticatorSelection.requireResidentKey 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 muss eine auffindbare Anmeldedaten erstellt werden. Wenn sie nicht erstellt werden kann, wirdNotSupportedErrorzurückgegeben.'preferred': Die vertrauende Partei bevorzugt die Erstellung einer auffindbaren Anmeldedaten, akzeptiert aber auch eine nicht auffindbare Anmeldedaten.'discouraged': Die vertrauende Partei bevorzugt die Erstellung einer nicht auffindbaren Anmeldedaten, akzeptiert aber auch eine auffindbare Anmeldedaten.
requireResidentKey:
- Dieses Attribut wird aus Gründen der Abwärtskompatibilität mit WebAuthn Level 1, einer älteren Version der Spezifikation, beibehalten. Setzen Sie es auf
true, wennresidentKeyauf'required'gesetzt ist, andernfalls auffalse.
allowCredentials
Vertrauende Parteien können allowCredentials für navigator.credentials.get() verwenden, um die Passkey-Authentifizierung zu steuern. In der Regel gibt es drei Arten der Passkey-Authentifizierung:
Modale Kontoauswahl anzeigen
Mit auffindbaren Anmeldedaten können vertrauende Parteien eine modale Kontoauswahl anzeigen, damit der Nutzer ein Konto für die Anmeldung auswählen kann. Anschließend erfolgt die Nutzerbestätigung. Dies eignet sich für den Passkey-Authentifizierungsablauf, der durch Klicken auf eine Schaltfläche für die Passkey-Authentifizierung ausgelöst wird.
Um diese Nutzererfahrung zu erzielen, lassen Sie den Parameter allowCredentials in navigator.credentials.get() weg 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. Für Nutzer, die keine lokalen Passkeys haben, wird das modale Dialogfeld trotzdem angezeigt und sie werden aufgefordert, einen Passkey von einem anderen Gerät zu präsentieren. Während Sie Ihre Nutzer auf Passkeys umstellen, möchten Sie diese Benutzeroberfläche möglicherweise für Nutzer vermeiden, die noch keinen Passkey eingerichtet haben.
Stattdessen kann die Auswahl eines Passkeys in die Autofill-Aufforderungen für die Felder in einem herkömmlichen Anmeldeformular aufgenommen werden, zusammen mit gespeicherten Nutzernamen und Passwörtern. So kann ein Nutzer mit Passkeys das Anmeldeformular ausfüllen, indem er seinen Passkey auswählt. Nutzer mit gespeicherten Nutzername/Passwort-Paaren können diese auswählen und Nutzer ohne beides können ihren Nutzernamen und ihr Passwort eingeben.
Diese Nutzererfahrung ist ideal, wenn die vertrauende Partei eine Migration mit gemischter Verwendung von Passwörtern und Passkeys durchführt.
Um diese Nutzererfahrung zu erzielen, geben Sie zusätzlich zum Übergeben eines leeren Arrays an das allowCredentials Attribut oder zum Weglassen des Parameters mediation: 'conditional' für navigator.credentials.get() an und versehen Sie ein HTML username Eingabefeld mit autocomplete="username webauthn" oder ein password Eingabefeld mit autocomplete="password webauthn".
Der Aufruf von navigator.credentials.get() führt nicht dazu, dass eine Benutzeroberfläche angezeigt wird. Wenn der Nutzer jedoch das annotierte Eingabefeld fokussiert, werden alle verfügbaren Passkeys in die Autofill-Optionen aufgenommen. Wenn der Nutzer einen Passkey auswählt, wird die normale Geräteentsperrungsbestätigung durchgeführt. Erst dann wird das von .get() zurückgegebene Promise mit einem Ergebnis aufgelöst. Wenn der Nutzer keinen Passkey auswählt, wird das Promise nie aufgelöst.
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" ...>
Informationen zum Erstellen dieser Nutzererfahrung finden Sie unter Mit einem Passkey über Autofill für Formulare anmelden sowie im Codelab Passkeys mit Autofill für Formulare in einer Webanwendung implementieren.
Erneute Authentifizierung
In einigen Fällen, z. B. bei der Verwendung von Passkeys für die erneute Authentifizierung, ist die ID des Nutzers bereits bekannt. In diesem Fall möchten wir einen Passkey verwenden, ohne dass der Browser oder das Betriebssystem eine Kontoauswahl anzeigt. Dazu können Sie eine Liste von Anmeldedaten-IDs im Parameter allowCredentials übergeben.
Wenn in diesem Fall eine der genannten Anmeldedaten lokal verfügbar ist, wird der Nutzer sofort aufgefordert, das Gerät zu entsperren. Andernfalls wird der Nutzer aufgefordert, ein anderes Gerät (ein Smartphone oder einen Sicherheitsschlüssel) zu präsentieren, das gültige Anmeldedaten enthält.
Um diese Nutzererfahrung zu erzielen, geben Sie eine Liste von Anmeldedaten-IDs für den anmeldenden Nutzer an. Die vertrauende Partei sollte sie abfragen können, da der Nutzer bereits bekannt ist. Geben Sie Anmeldedaten-IDs als PublicKeyCredentialDescriptor-Objekte im Attribut 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 öffentlichen Schlüsselanmeldedaten, die die vertrauende Partei bei der Passkey-Registrierung erhalten hat.type: Dieses Feld ist normalerweise'public-key'.transports: Ein Hinweis auf die vom Gerät unterstützten Übertragungsprotokolle, das von Browsern verwendet wird, um die Benutzeroberfläche zu optimieren, die den Nutzer auffordert, ein externes Gerät zu präsentieren. Diese Liste sollte, falls vorhanden, das Ergebnis des Aufrufs vongetTransports()während der Registrierung jeder Anmeldedaten enthalten.
Zusammenfassung
Auffindbare Anmeldedaten machen die Passkey-Anmeldung viel nutzerfreundlicher, da der Nutzer keinen Nutzernamen eingeben muss. Mit der Kombination aus residentKey, requireResidentKey und allowCredentials können vertrauende Parteien Anmeldeverfahren erstellen, die:
- eine modale Kontoauswahl anzeigen.
- Autofill für Passkey-Formulare anzeigen.
- eine erneute Authentifizierung ermöglichen.
Verwenden Sie auffindbare Anmeldedaten mit Bedacht. So können Sie ausgefeilte Passkey-Anmeldeverfahren entwickeln, die für Nutzer nahtlos funktionieren und mit denen sie eher interagieren.