Unter Android 15 unterstützt der Credential Manager einen Single-Tap-Vorgang zum Erstellen und Abrufen von Anmeldedaten. In diesem Ablauf werden die Informationen des erstellten oder verwendeten Ausweises direkt in der biometrischen Aufforderung angezeigt, zusammen mit einem Einstiegspunkt zu weiteren Optionen. Dieser vereinfachte Prozess ermöglicht eine effizientere und optimierte Erstellung und Abfrage von Anmeldedaten.
Voraussetzungen:
- Auf dem Gerät des Nutzers wurden biometrische Daten eingerichtet und der Nutzer erlaubt die Verwendung dieser Daten für die Authentifizierung in Anwendungen.
- Bei Anmeldeabläufen ist diese Funktion nur für Szenarien mit einem einzelnen Konto aktiviert, auch wenn für dieses Konto mehrere Anmeldedaten (z. B. Passkey und Passwort) verfügbar sind.
Einmaliges Tippen bei der Passkey-Erstellung aktivieren
Die Schritte zur Erstellung dieser Methode entsprechen dem vorhandenen Prozess zur Erstellung von Anmeldedaten. Verwenden Sie in Ihrer BeginCreatePublicKeyCredentialRequest die Methode handleCreatePasskeyQuery(), um die Anfrage zu verarbeiten, wenn es sich um einen Passkey handelt.
is BeginCreatePublicKeyCredentialRequest -> {
Log.i(TAG, "Request is passkey type")
return handleCreatePasskeyQuery(request, passwordCount, passkeyCount)
}
Fügen Sie in der handleCreatePasskeyQuery()-Datei BiometricPromptData mit der Klasse CreateEntry ein:
val createEntry = CreateEntry(
// Additional properties...
biometricPromptData = BiometricPromptData(
allowedAuthenticators = allowedAuthenticator
),
)
Anbieter von Anmeldedaten sollten das Attribut allowedAuthenticator in der BiometricPromptData-Instanz explizit festlegen. Wenn dieses Attribut nicht festgelegt ist, wird der Wert standardmäßig auf DEVICE_WEAK gesetzt. Legen Sie die optionale Property cryptoObject fest, wenn dies für Ihren Anwendungsfall erforderlich ist.
Einmaliges Tippen bei der Anmeldung mit Passkey aktivieren
Ähnlich wie beim Erstellen von Passkeys wird hier die vorhandene Einrichtung für die Verarbeitung der Nutzeranmeldung verwendet. Verwenden Sie unter BeginGetPublicKeyCredentialOption die Option populatePasskeyData(), um die relevanten Informationen zur Authentifizierungsanfrage zu erfassen:
is BeginGetPublicKeyCredentialOption -> {
// ... other logic
populatePasskeyData(
origin,
option,
responseBuilder,
autoSelectEnabled,
allowedAuthenticator
)
// ... other logic as needed
}
Ähnlich wie bei CreateEntry wird eine BiometricPromptData-Instanz auf die PublicKeyCredentialEntry-Instanz festgelegt. Wenn nicht explizit festgelegt, wird für allowedAuthenticator standardmäßig BIOMETRIC_WEAK verwendet.
PublicKeyCredentialEntry(
// other properties...
biometricPromptData = BiometricPromptData(
allowedAuthenticators = allowedAuthenticator
)
)
Auswahl des Anmeldedateneintrags verarbeiten
Wenn Sie die Auswahl des Anmeldedateneintrags für die Passkey-Erstellung oder die Passkey-Auswahl bei der Anmeldung verarbeiten, rufen Sie je nach Bedarf PendingIntentHandler's
retrieveProviderCreateCredentialRequest oder retrieveProviderGetCredentialRequest auf. Diese geben Objekte zurück, die die für den Anbieter erforderlichen Metadaten enthalten. Wenn Sie beispielsweise die Auswahl des Eintrags für die Passkey-Erstellung verarbeiten, aktualisieren Sie Ihren Code so:
val createRequest = PendingIntentHandler.retrieveProviderCreateCredentialRequest(intent)
if (createRequest == null) {
Log.i(TAG, "request is null")
setUpFailureResponseAndFinish("Unable to extract request from intent")
return
}
// Other logic...
val biometricPromptResult = createRequest.biometricPromptResult
// Add your logic based on what needs to be done
// after getting biometrics
if (createRequest.callingRequest is CreatePublicKeyCredentialRequest) {
val publicKeyRequest: CreatePublicKeyCredentialRequest =
createRequest.callingRequest as CreatePublicKeyCredentialRequest
if (biometricPromptResult == null) {
// Do your own authentication flow, if needed
} else if (biometricPromptResult.isSuccessful) {
createPasskey(
publicKeyRequest.requestJson,
createRequest.callingAppInfo,
publicKeyRequest.clientDataHash,
accountId
)
} else {
val error = biometricPromptResult.authenticationError
// Process the error
}
// Other logic...
}
Dieses Beispiel enthält Informationen zum Erfolg des biometrischen Ablaufs. Sie enthält auch andere Informationen zum Berechtigungsnachweis. Wenn der Ablauf fehlschlägt, verwenden Sie den Fehlercode unter biometricPromptResult.authenticationError, um Entscheidungen zu treffen.
Die Fehlercodes, die als Teil von biometricPromptResult.authenticationError.errorCode zurückgegeben werden, sind dieselben Fehlercodes, die in der androidx.biometric-Bibliothek definiert sind, z. B. androidx.biometric.BiometricPrompt.ERROR_NO_SPACE, androidx.biometric.BiometricPrompt.ERROR_UNABLE_TO_PROCESS, androidx.biometric.BiometricPrompt.ERROR_TIMEOUT und ähnliche. Der authenticationError enthält auch eine Fehlermeldung, die mit dem errorCode verknüpft ist und auf einer Benutzeroberfläche angezeigt werden kann.
Extrahieren Sie auf ähnliche Weise Metadaten während der retrieveProviderGetCredentialRequest.
Prüfen Sie, ob der biometrische Ablauf null ist. Wenn ja, konfigurieren Sie Ihre eigenen biometrischen Daten für die Authentifizierung. Dies ähnelt der Instrumentierung des get-Vorgangs:
val getRequest =
PendingIntentHandler.retrieveProviderGetCredentialRequest(intent)
if (getRequest == null) {
Log.i(TAG, "request is null")
setUpFailureResponseAndFinish("Unable to extract request from intent")
return
}
// Other logic...
val biometricPromptResult = getRequest.biometricPromptResult
// Add your logic based on what needs to be done
// after getting biometrics
if (biometricPromptResult == null) {
// Do your own authentication flow, if necessary
} else if (biometricPromptResult.isSuccessful) {
Log.i(TAG, "The response from the biometricPromptResult was ${biometricPromptResult.authenticationResult?.authenticationType}")
validatePasskey(
publicKeyRequest.requestJson,
origin,
packageName,
uid,
passkey.username,
credId,
privateKey
)
} else {
val error = biometricPromptResult.authenticationError
// Process the error
}
// Other logic...