Erstellen von Passkeys und Anmeldung durch einmaliges Tippen in biometrische Prompts einbinden

Unter Android 15 unterstützt der Anmeldedaten-Manager einen Single-Tap-Ablauf zum Erstellen und Abrufen von Anmeldedaten. In diesem Ablauf werden die Informationen der Anmeldedaten, die erstellt oder verwendet werden, direkt im biometrischen Prompt zusammen mit einem Einstiegspunkt für weitere Optionen angezeigt. Dieser vereinfachte Prozess sorgt für eine effizientere und optimierte Erstellung und den Abruf von Anmeldedaten.

Voraussetzungen:

  • Auf dem Gerät des Nutzers wurde ein biometrisches Verfahren eingerichtet und der Nutzer erlaubt die Verwendung für die Authentifizierung in Anwendungen.
  • Bei Anmeldevorgängen ist diese Funktion nur für Szenarien mit einem 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 zum Erstellen dieser Methode entsprechen dem bestehenden Prozess zum Erstellen von Anmeldedaten. Verwenden Sie in Ihrem BeginCreatePublicKeyCredentialRequest 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 handleCreatePasskeyQuery() BiometricPromptData mit der Klasse CreateEntry ein:

val createEntry = CreateEntry(
    // Additional properties...
    biometricPromptData = BiometricPromptData(
        allowedAuthenticators = allowedAuthenticator
    ),
)

Anbieter von Anmeldedaten sollten die Eigenschaft allowedAuthenticator in der BiometricPromptData-Instanz explizit festlegen. Wenn diese Eigenschaft nicht festgelegt ist, wird standardmäßig DEVICE_WEAK verwendet. Legen Sie bei Bedarf die optionale Property cryptoObject für Ihren Anwendungsfall fest.

Anmeldung mit nur einmal tippen in Passkey-Abläufen aktivieren

Ähnlich wie beim Erstellen von Passkeys wird hier die vorhandene Einrichtung für die Anmeldung von Nutzern verwendet. Verwenden Sie unter BeginGetPublicKeyCredentialOption die Funktion 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 automatisch die Standardeinstellung BIOMETRIC_WEAK verwendet.

PublicKeyCredentialEntry(
    // other properties...

    biometricPromptData = BiometricPromptData(
        allowedAuthenticators = allowedAuthenticator
    )
)

Auswahl der Anmeldedateneingabe verarbeiten

Rufen Sie beim Verarbeiten der Auswahl der Anmeldedateneingabe für die Passkey-Erstellung oder die Passkey-Auswahl bei der Anmeldung die 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 Erstellung von Passkeys verarbeiten, aktualisieren Sie Ihren Code wie unten gezeigt:

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. Es enthält auch andere Informationen zum Anmeldedaten. 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.NO_SPACE, androidx.biometric.BiometricPrompt.UNABLE_TO_PROCESS und androidx.biometric.BiometricPrompt.ERROR_TIMEOUT. Das authenticationError enthält auch eine Fehlermeldung, die mit dem errorCode verknüpft ist und auf einer Benutzeroberfläche angezeigt werden kann.

Extrahieren Sie Metadaten während der retrieveProviderGetCredentialRequest. Prüfen Sie, ob Ihr biometrischer Ablauf null ist. Wenn ja, konfigurieren Sie Ihre eigenen biometrischen Verfahren für die Authentifizierung. Das ist ähnlich wie beim Abrufen von Vorgängen:

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...