Revision 2024 Q4: Learn how to simplify auth journeys using Credential Manager API in your Android app

1. Hinweis

Traditionelle Authentifizierungslösungen stellen eine Reihe von Sicherheits- und Nutzerfreundlichkeitsproblemen dar.

Passwörter werden häufig verwendet, aber…

  • Leicht vergessen
  • Nutzer benötigen Wissen, um starke Passwörter zu erstellen.
  • Sie können von Angreifern leicht gephisht, abgerufen und wiedergegeben werden.

Android hat die Credential Manager API entwickelt, um die Anmeldung zu vereinfachen und Sicherheitsrisiken zu minimieren. Dazu werden Passkeys unterstützt, der neue Branchenstandard für die passwortlose Authentifizierung.

Der Anmeldedaten-Manager unterstützt Passkeys und kombiniert sie mit traditionellen Authentifizierungsmethoden wie Passwörtern und „Über Google anmelden“.

Nutzer können Passkeys erstellen und im Google Passwortmanager speichern. Diese Passkeys werden dann auf allen Android-Geräten synchronisiert, auf denen der Nutzer angemeldet ist. Ein Passkey muss erstellt, mit einem Nutzerkonto verknüpft und sein öffentlicher Schlüssel auf einem Server gespeichert werden, bevor sich ein Nutzer damit anmelden kann.

In diesem Codelab erfahren Sie, wie Sie sich mit Passkeys und einem Passwort über die Credential Manager API registrieren und sie für zukünftige Authentifizierungszwecke verwenden. Es gibt zwei Abläufe:

  • Registrierung : Mit Passkeys und Passwort
  • Anmeldung : Mit Passkeys und gespeichertem Passwort

Vorbereitung

  • Grundlegende Kenntnisse zum Ausführen von Apps in Android Studio
  • Grundlegende Kenntnisse des Authentifizierungsablaufs in Android-Apps
  • Grundlegende Kenntnisse zu Passkeys

Lerninhalte

  • So erstellen Sie einen Passkey.
  • So speichern Sie ein Passwort im Passwortmanager.
  • So authentifizieren Sie Nutzer mit einem Passkey oder einem gespeicherten Passwort.

Voraussetzungen

Eine der folgenden Gerätekombinationen:

  • Ein Android-Gerät mit Android 9 oder höher (für Passkeys) und Android 4.4 oder höher(für die Passwortauthentifizierung über die Credential Manager API).
  • Gerät mit möglichst einem biometrischen Sensor
  • Registrieren Sie ein biometrisches Verfahren oder eine Displaysperre.
  • Kotlin-Plug-in-Version : 1.8.10

2. Einrichten

  1. Klonen Sie dieses Repository auf Ihrem Laptop aus dem Branch credman_codelab : https://github.com/android/identity-samples/tree/credman_codelab
git clone -b credman_codelab https://github.com/android/identity-samples.git
  1. Rufen Sie das Modul CredentialManager auf und öffnen Sie das Projekt in Android Studio.

Sehen wir uns den Anfangsstatus der App an.

So sehen Sie, wie der Anfangsstatus der App funktioniert:

  1. Starten Sie die App.
  2. Sie sehen einen Hauptbildschirm mit den Schaltflächen „Registrieren“ und „Anmelden“. Diese Schaltflächen haben noch keine Funktion, werden aber in den folgenden Abschnitten aktiviert.

7a6fe80f4cf877a8.jpeg

3. Möglichkeit zur Registrierung mit Passkeys hinzufügen

Wenn Nutzer sich in einer Android-App, die die Credential Manager API verwendet, für ein neues Konto registrieren, können sie einen Passkey für ihr Konto erstellen. Dieser Passkey wird sicher beim ausgewählten Anmeldedatenanbieter des Nutzers gespeichert und für zukünftige Anmeldungen verwendet, ohne dass der Nutzer jedes Mal sein Passwort eingeben muss.

Jetzt erstellen Sie einen Passkey und registrieren Nutzeranmeldedaten mithilfe von Biometrie/Displaysperre.

Mit Passkey registrieren

Der Code in Credential Manager/app/main/java/SignUpFragment.kt definiert ein Textfeld „username“ und eine Schaltfläche zum Registrieren mit einem Passkey.

1f4c50daa2551f1.jpeg

Übergeben Sie die Herausforderung und die andere JSON-Antwort an einen createPasskey()-Aufruf.

Bevor ein Passkey erstellt wird, müssen Sie vom Server die erforderlichen Informationen anfordern, die beim Aufruf von createCredential() an die Credential Manager API übergeben werden.

In den Assets Ihres Projekts befindet sich bereits eine Mock-Antwort namens RegFromServer.txt, die die erforderlichen Parameter in diesem Codelab zurückgibt.

  • Rufen Sie in Ihrer App SignUpFragment.kt auf und suchen Sie nach der Methode signUpWithPasskeys. Dort schreiben Sie die Logik zum Erstellen eines Passkeys und zum Anmelden des Nutzers. Sie finden die Methode in derselben Klasse.
  • Kommentieren Sie den else-Block, um createPasskey() aufzurufen, und ersetzen Sie ihn durch den folgenden Code:

SignUpFragment.kt

//TODO : Call createPasskey() to signup with passkey

val data = createPasskey()

Diese Methode wird aufgerufen, sobald ein gültiger Nutzername auf dem Bildschirm eingegeben wurde.

  • Innerhalb der createPasskey()-Methode musst du eine CreatePublicKeyCredentialRequest() mit den erforderlichen zurückgegebenen Parametern erstellen.

SignUpFragment.kt

//TODO create a CreatePublicKeyCredentialRequest() with necessary registration json from server

val request = CreatePublicKeyCredentialRequest(fetchRegistrationJsonFromServer())

Die fetchRegistrationJsonFromServer()-Methode liest eine emulierte Server-PublicKeyCredentialCreationOptions-JSON-Antwort aus Assets und gibt die Registrierungs-JSON zurück, die beim Erstellen des Passkeys übergeben werden soll.

  • Suchen Sie die Methode fetchRegistrationJsonFromServer() und ersetzen Sie das TODO durch den folgenden Code, um JSON zurückzugeben. Entfernen Sie auch die Rückgabeanweisung für den leeren String :

SignUpFragment.kt

//TODO fetch registration mock response

val response = requireContext().readFromAsset("RegFromServer")

//Update userId,challenge, name and Display name in the mock
return response.replace("<userId>", getEncodedUserId())
   .replace("<userName>", binding.username.text.toString())
   .replace("<userDisplayName>", binding.username.text.toString())
   .replace("<challenge>", getEncodedChallenge())
  • Diese JSON-Datei ist unvollständig und enthält vier Felder, die ersetzt werden müssen.
  • Die UserId muss eindeutig sein, damit ein Nutzer bei Bedarf mehrere Passkeys erstellen kann. Ersetzen Sie <userId> durch den generierten userId-Wert.
  • <challenge> muss ebenfalls eindeutig sein, damit eine zufällige, eindeutige Herausforderung generiert wird. Die Methode ist bereits in Ihrem Code enthalten.

Eine echte Server-PublicKeyCredentialCreationOptions-Antwort kann mehr Optionen zurückgeben. Unten finden Sie einige Beispiele für diese Felder:

{
  "challenge": String,
  "rp": {
    "name": String,
    "id": String
  },
  "user": {
    "id": String,
    "name": String,
    "displayName": String
  },
  "pubKeyCredParams": [
    {
      "type": "public-key",
      "alg": -7
    },
    {
      "type": "public-key",
      "alg": -257
    }
  ],
  "timeout": 1800000,
  "attestation": "none",
  "excludeCredentials": [],
  "authenticatorSelection": {
    "authenticatorAttachment": "platform",
    "requireResidentKey": true,
    "residentKey": "required",
    "userVerification": "required"
  }
}

In der folgenden Tabelle werden einige der wichtigsten Parameter in einem PublicKeyCredentialCreationOptions-Objekt erläutert:

Parameter

Textzeilen

challenge

Ein servergenerierter Zufallsstring, der genügend Entropie enthält, um das Erraten zu erschweren. Sie sollte mindestens 16 Byte lang sein. Dieser Wert ist erforderlich, wird aber bei der Registrierung nicht verwendet, es sei denn, es wird eine Attestierung durchgeführt.

user.id

Die eindeutige ID eines Nutzers. Dieser Wert darf keine personenidentifizierbaren Informationen wie E-Mail-Adressen oder Nutzernamen enthalten. Ein zufällig generierter Wert von 16 Byte pro Konto ist gut geeignet.

user.name

Dieses Feld sollte eine eindeutige Kennung für das Konto enthalten, die der Nutzer erkennt, z. B. seine E-Mail-Adresse oder seinen Nutzernamen. Dieser wird in der Kontoauswahl angezeigt. Wenn Sie einen Nutzernamen verwenden, verwenden Sie denselben Wert wie bei der Passwortauthentifizierung.

user.displayName

Dieses Feld ist ein optionaler, nutzerfreundlicherer Name für das Konto.

rp.id

Die Entität der vertrauenden Partei entspricht den Details Ihrer Anwendung. Es hat die folgenden Attribute:

  • name (erforderlich): der Name Ihrer Anwendung
  • ID (optional): entspricht der Domain oder Subdomain. Wenn keine Angabe gemacht wird, wird die aktuelle Domain verwendet.
  • icon (optional).

pubKeyCredParams

Liste der zulässigen Algorithmen und Schlüsseltypen. Diese Liste muss mindestens ein Element enthalten.

excludeCredentials

Der Nutzer, der versucht, ein Gerät zu registrieren, hat möglicherweise bereits andere Geräte registriert. Wenn Sie das Erstellen mehrerer Anmeldedaten für dasselbe Konto in einem einzigen Authenticator einschränken möchten, können Sie diese Geräte ignorieren. Das Mitglied transports, falls angegeben, sollte das Ergebnis des Aufrufs von getTransports() während der Registrierung der einzelnen Anmeldedaten enthalten.

authenticatorSelection.authenticatorAttachment

Gibt an, ob das Gerät an der Plattform befestigt werden soll oder nicht oder ob dies nicht erforderlich ist. Legen Sie diesen Wert auf platform fest. Sie möchten also einen Authenticator, der in das Plattformgerät eingebettet ist. Der Nutzer wird nicht aufgefordert, z. B. einen USB-Sicherheitsschlüssel einzulegen.

residentKey

Geben Sie den Wert required an, um einen Passkey zu erstellen.

Anmeldedaten erstellen

  1. Nachdem du einen CreatePublicKeyCredentialRequest() erstellt hast, musst du den createCredential()-Aufruf mit der erstellten Anfrage aufrufen.

SignUpFragment.kt

//TODO call createCredential() with createPublicKeyCredentialRequest

try {
   response = credentialManager.createCredential(
       requireActivity(),
       request
   ) as CreatePublicKeyCredentialResponse
} catch (e: CreateCredentialException) {
   configureProgress(View.INVISIBLE)
   handlePasskeyFailure(e)
}
  • Sie geben die erforderlichen Informationen an createCredential() weiter.
  • Sobald die Anfrage erfolgreich war, wird auf dem Bildschirm ein Unterbrechungsbereich angezeigt, in dem Sie aufgefordert werden, einen Passkey zu erstellen.
  • Nutzer können ihre Identität jetzt beispielsweise über biometrische Verfahren oder die Displaysperre bestätigen.
  • Sie steuern die Sichtbarkeit der gerenderten Ansichten und die Ausnahmen, wenn die Anfrage aus irgendeinem Grund fehlschlägt. Hier werden die Fehlermeldungen protokolliert und in der App in einem Fehlerdialogfeld angezeigt. Sie können die vollständigen Fehlerprotokolle über Android Studio oder den Befehl adb debug prüfen.

1ea8ace66135de1e.png

  1. Abschließend müssen Sie die Registrierung abschließen. Die App sendet Anmeldedaten für öffentliche Schlüssel an den Server, der sie für den aktuellen Nutzer registriert.

Hier haben wir einen Mock-Server verwendet. Daher geben wir einfach „wahr“ zurück, um anzugeben, dass der Server den registrierten öffentlichen Schlüssel zu zukünftigen Authentifizierungs- und Validierungszwecken gespeichert hat. Weitere Informationen zur serverseitigen Passkey-Registrierung für Ihre eigene Implementierung

Suchen Sie in der Methode signUpWithPasskeys() nach dem entsprechenden Kommentar und ersetzen Sie ihn durch den folgenden Code:

SignUpFragment.kt

//TODO : complete the registration process after sending public key credential to your server and let the user in

data?.let {
   registerResponse()
   DataProvider.setSignedInThroughPasskeys(true)
   listener.showHome()
}
  • registerResponse() gibt true zurück, was bedeutet, dass der Mock-Server den öffentlichen Schlüssel für die spätere Verwendung gespeichert hat.
  • Legen Sie für das Flag setSignedInThroughPasskeys den Wert true fest.
  • Nach der Anmeldung werden Nutzer zum Startbildschirm weitergeleitet.

Ein echter PublicKeyCredential kann mehr Felder enthalten. Ein Beispiel für diese Felder ist unten zu sehen:

{
  "id": String,
  "rawId": String,
  "type": "public-key",
  "response": {
    "clientDataJSON": String,
    "attestationObject": String,
  }
}

In der folgenden Tabelle werden einige der wichtigsten Parameter in einem PublicKeyCredential-Objekt erläutert:

Parameter

Textzeilen

id

Eine Base64URL-codierte ID des erstellten Passkeys. Anhand dieser ID kann der Browser bei der Authentifizierung feststellen, ob sich auf dem Gerät ein passender Passkey befindet. Dieser Wert muss in der Datenbank im Backend gespeichert werden.

rawId

Eine ArrayBuffer-Objektversion der Anmeldedaten-ID.

response.clientDataJSON

Clientdaten, die in einem ArrayBuffer-Objekt codiert sind.

response.attestationObject

Ein mit ArrayBuffer codiertes Attestierungsobjekt. Sie enthält wichtige Informationen wie eine RP-ID, Flags und einen öffentlichen Schlüssel.

Wenn Sie die App starten, können Sie auf die Schaltfläche Über Passkeys registrieren klicken und einen Passkey erstellen.

4. Passwort im Anmeldedatenanbieter speichern

In dieser App ist auf dem Bildschirm „Registrieren“ bereits eine Registrierung mit Nutzername und Passwort zu Demonstrationszwecken implementiert.

Um die Anmeldedaten des Nutzerpassworts beim Passwortanbieter zu speichern, implementieren Sie einen CreatePasswordRequest, der an createCredential() übergeben wird, um das Passwort zu speichern.

  • Suchen Sie die signUpWithPassword()-Methode und ersetzen Sie das TODO durch einen createPassword-Aufruf:

SignUpFragment.kt

//TODO : Save the user credential password with their password provider

createPassword()
  • In der Methode createPassword() müssen Sie eine Passwort-Anfrage erstellen. Ersetzen Sie das TODO durch den folgenden Code:

SignUpFragment.kt

//TODO : CreatePasswordRequest with entered username and password

val request = CreatePasswordRequest(
   binding.username.text.toString(),
   binding.password.text.toString()
)
  • Erstellen Sie als Nächstes in der createPassword()-Methode Anmeldedaten mit einer Anfrage zum Erstellen eines Passworts und speichern Sie die Anmeldedaten des Nutzers beim Passwortanbieter. Ersetzen Sie das TODO durch den folgenden Code:

SignUpFragment.kt

//TODO : Create credential with created password request


try {
   credentialManager.createCredential(requireActivity(), request) as CreatePasswordResponse
} catch (e: Exception) {
   Log.e("Auth", " Exception Message : " + e.message)
}
  • Sie haben die Anmeldedaten für das Passwort beim Passwortanbieter des Nutzers gespeichert, damit er sich mit nur einem Tippen mit einem Passwort authentifizieren kann.

5. Authentifizierung mit einem Passkey oder Passwort hinzufügen

Sie können es jetzt verwenden, um sich sicher in Ihrer App zu authentifizieren.

76e81460b26f9798.png

Herausforderung und andere Optionen abrufen, die an den getPasskey()-Aufruf übergeben werden sollen

Bevor Sie den Nutzer zur Authentifizierung auffordern, müssen Sie Parameter anfordern, die Sie in WebAuthn JSON vom Server übergeben, einschließlich einer Herausforderung.

In Ihren Assets befindet sich bereits eine Mock-Antwort (AuthFromServer.txt), die in diesem Codelab solche Parameter zurückgibt.

  • Rufen Sie in Ihrer App „SignInFragment.kt“ auf und suchen Sie die Methode signInWithSavedCredentials, in der Sie die Logik für die Authentifizierung über einen gespeicherten Passkey oder ein Passwort schreiben und den Nutzer zulassen:
  • Kommentieren Sie den else-Block, um createPasskey() aufzurufen, und ersetzen Sie ihn durch den folgenden Code:

SignInFragment.kt

//TODO : Call getSavedCredentials() method to signin using passkey/password

val data = getSavedCredentials()
  • In der Methode „getSavedCredentials()“ müssen Sie eine GetPublicKeyCredentialOption() mit den erforderlichen Parametern zum Abrufen von Anmeldedaten von Ihrem Anmeldedatenanbieter erstellen.

SigninFragment.kt

//TODO create a GetPublicKeyCredentialOption() with necessary registration json from server

val getPublicKeyCredentialOption =
   GetPublicKeyCredentialOption(fetchAuthJsonFromServer(), null)

Die Methode fetchAuthJsonFromServer() liest die JSON-Authentifizierungsantwort aus den Assets und gibt JSON-Authentifizierungsdaten zurück, um alle Passkeys abzurufen, die mit diesem Nutzerkonto verknüpft sind.

Der zweite Parameter von GetPublicKeyCredentialOption() ist clientDataHash, ein Hashwert, der zum Verifizieren der Identität der vertrauenden Seite verwendet wird. Legen Sie dies nur fest, wenn Sie den GetCredentialRequest.origin festgelegt haben. Für die Beispiel-App ist dies auf null festgelegt.

  • Suchen Sie die Methode „fetchAuthJsonFromServer()“ und ersetzen Sie das TODO durch den folgenden Code, um JSON zurückzugeben. Entfernen Sie außerdem die Rückgabeanweisung für den leeren String:

SignInFragment.kt

//TODO fetch authentication mock json

return requireContext().readFromAsset("AuthFromServer")

Hinweis : Der Server dieses Codelabs ist so konzipiert, dass er ein JSON-Objekt zurückgibt, das dem Wörterbuch PublicKeyCredentialRequestOptions möglichst ähnlich ist, das an den getCredential()-Aufruf der API übergeben wird. Das folgende Code-Snippet enthält einige Beispieloptionen, die in einer echten Antwort enthalten sein könnten:

{
  "challenge": String,
  "rpId": String,
  "userVerification": "",
  "timeout": 1800000
}

In der folgenden Tabelle werden einige der wichtigsten Parameter in einem PublicKeyCredentialRequestOptions-Objekt erläutert:

Parameter

Textzeilen

challenge

Eine servergenerierte Herausforderung in einem ArrayBuffer-Objekt. Dies ist erforderlich, um Wiederholungsversuche zu verhindern. Nimm niemals dieselbe Herausforderung in einer Antwort zweimal an. Sie können es als CSRF-Token betrachten.

rpId

Eine RP-ID ist eine Domain. Für eine Website kann entweder die Domain oder ein registrierbares Suffix angegeben werden. Dieser Wert muss mit dem Parameter rp.id übereinstimmen, der beim Erstellen des Passkeys verwendet wurde.

  • Als Nächstes müssen Sie ein PasswordOption()-Objekt erstellen, um alle in Ihrem Passwortanbieter über die Credential Manager API gespeicherten Passwörter für dieses Nutzerkonto abzurufen. Suchen Sie in der Methode getSavedCredentials() nach dem TODO und ersetzen Sie es durch Folgendes:

SigninFragment.kt

//TODO create a PasswordOption to retrieve all the associated user's password

val getPasswordOption = GetPasswordOption()

Anmeldedaten abrufen

  • Als Nächstes musst du die getCredential()-Anfrage mit allen oben genannten Optionen aufrufen, um die zugehörigen Anmeldedaten abzurufen:

SignInFragment.kt

//TODO call getCredential() with required credential options

val result = try {
   credentialManager.getCredential(
       requireActivity(),
       GetCredentialRequest(
           listOf(
               getPublicKeyCredentialOption,
               getPasswordOption
           )
     )
   )
} catch (e: Exception) {
   configureViews(View.INVISIBLE, true)
   Log.e("Auth", "getCredential failed with exception: " + e.message.toString())
   activity?.showErrorAlert(
       "An error occurred while authenticating through saved credentials. Check logs for additional details"
   )
   return null
}

if (result.credential is PublicKeyCredential) {
   val cred = result.credential as PublicKeyCredential
   DataProvider.setSignedInThroughPasskeys(true)
   return "Passkey: ${cred.authenticationResponseJson}"
}
if (result.credential is PasswordCredential) {
   val cred = result.credential as PasswordCredential
   DataProvider.setSignedInThroughPasskeys(false)
   return "Got Password - User:${cred.id} Password: ${cred.password}"
}
if (result.credential is CustomCredential) {
   //If you are also using any external sign-in libraries, parse them here with the utility functions provided.
}

  • Sie geben die erforderlichen Informationen an getCredential() weiter. Dazu werden die Anmeldedatenoptionen und ein Aktivitätskontext verwendet, um die Optionen im unteren Bereich in diesem Kontext zu rendern.
  • Sobald die Anfrage erfolgreich war, wird auf dem Bildschirm eine Bottomsheet mit allen erstellten Anmeldedaten für das verknüpfte Konto angezeigt.
  • Nutzer können jetzt ihre Identität über biometrische Verfahren oder die Displaysperre bestätigen, um die ausgewählten Anmeldedaten zu authentifizieren.
  • Wenn die ausgewählten Anmeldedaten PublicKeyCredential sind, setzen Sie das setSignedInThroughPasskeys-Flag auf true. Setzen Sie es andernfalls auf false.

Das folgende Code-Snippet enthält ein Beispiel für ein PublicKeyCredential-Objekt:

{
  "id": String
  "rawId": String
  "type": "public-key",
  "response": {
    "clientDataJSON": String
    "authenticatorData": String
    "signature": String
    "userHandle": String
  }
}

Die folgende Tabelle ist nicht vollständig, enthält aber die wichtigsten Parameter im PublicKeyCredential-Objekt:

Parameter

Textzeilen

id

Die Base64URL-codierte ID des authentifizierten Passkeys.

rawId

Eine ArrayBuffer-Objektversion der Anmeldedaten-ID.

response.clientDataJSON

Ein ArrayBuffer-Objekt mit Kundendaten. Dieses Feld enthält Informationen wie die Herausforderung und den Ursprung, die der RP-Server überprüfen muss.

response.authenticatorData

Ein ArrayBuffer-Objekt mit Authenticator-Daten. Dieses Feld enthält Informationen wie die RP-ID.

response.signature

Ein ArrayBuffer-Objekt der Signatur. Dieser Wert ist der Kern der Anmeldedaten und muss auf dem Server überprüft werden.

response.userHandle

Ein ArrayBuffer-Objekt, das die bei der Erstellung festgelegte Nutzer-ID enthält. Dieser Wert kann anstelle der Anmeldedaten-ID verwendet werden, wenn der Server die zu verwendenden ID-Werte auswählen muss oder wenn das Backend das Erstellen eines Index für Anmeldedaten-IDs vermeiden möchte.

  • Abschließend müssen Sie den Authentifizierungsvorgang abschließen. Normalerweise sendet die App nach Abschluss der Passkey-Authentifizierung einen öffentlichen Schlüssel mit einer Authentifizierungsbestätigung an den Server, der die Bestätigung überprüft und den Nutzer authentifiziert.

Hier haben wir einen Mock-Server verwendet, sodass wir einfach true zurückgeben, was bedeutet, dass der Server die Behauptung bestätigt hat. Weitere Informationen zur serverseitigen Passkey-Authentifizierung für Ihre eigene Implementierung

Suchen Sie in der Methode signInWithSavedCredentials() den entsprechenden Kommentar und ersetzen Sie ihn durch den folgenden Code:

SignInFragment.kt

//TODO : complete the authentication process after validating the public key credential to your server and let the user in.

data?.let {
   sendSignInResponseToServer()
   listener.showHome()
}
  • sendSigninResponseToServer() gibt „wahr“ zurück, was bedeutet, dass der (Mock-)Server den öffentlichen Schlüssel für die zukünftige Verwendung validiert hat.
  • Nach der Anmeldung werden Nutzer zum Startbildschirm weitergeleitet.

Öffnen Sie die App und gehen Sie zu Anmelden > Mit Passkeys/gespeichertem Passwort anmelden. Versuchen Sie,sich mit den gespeicherten Anmeldedaten anzumelden.

Ausprobieren

Sie haben in Ihrer Android-App die Erstellung von Passkeys, das Speichern von Passwörtern im Anmeldedaten-Manager und die Authentifizierung über Passkeys oder gespeicherte Passwörter mit der Anmeldedaten-Manager API implementiert.

6. Glückwunsch!

Sie haben dieses Codelab abgeschlossen. Die endgültige Lösung finden Sie unter https://github.com/android/identity-samples/tree/main/CredentialManager.

Wenn Sie Fragen haben, stellen Sie sie in Stack Overflow mit dem Tag passkey.

Weitere Informationen