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

Unter Android 15 unterstützt der Anmeldedaten-Manager einmaliges Tippen auf Anmeldedaten beim Erstellen und Abrufen. Bei diesem Ablauf werden die Informationen werden direkt im biometrischen Prompt angezeigt. mit einem Einstiegspunkt für mehr Optionen. Dieser vereinfachte Prozess erzeugt eine effizienter und rationalisierter Prozess zum Erstellen und Abrufen von Anmeldedaten.

Voraussetzungen:

  • Das biometrische Verfahren wurde auf dem Gerät des Nutzers eingerichtet und erlaubt in Anwendungen zu authentifizieren.
  • Für Anmeldeabläufe 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.

Abläufe zum Erstellen von Passkeys durch einmaliges Tippen aktivieren

Die Erstellungsschritte dieser Methode stimmen mit der vorhandenen Erstellung von Anmeldedaten überein Verwenden Sie in 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 Ihrem handleCreatePasskeyQuery() BiometricPromptData hinzu mit die Klasse CreateEntry:

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

Anmeldedatenanbieter sollten die Property allowedAuthenticator in der Instanz BiometricPromptData explizit festlegen. Wenn diese Eigenschaft nicht festgelegt ist, wird der Wert ist standardmäßig DEVICE_WEAK. Lege bei Bedarf das optionale Attribut cryptoObject fest. für Ihren Anwendungsfall.

Abläufe für Passkeys für die Anmeldung durch einmaliges Tippen aktivieren

Ähnlich wie beim Erstellen von Passkeys wird dabei die vorhandene Einrichtung für die Anmeldung von Nutzern verwendet. Verwenden Sie unter BeginGetPublicKeyCredentialOption populatePasskeyData(), um die relevanten Informationen Authentifizierungsanfrage:

is BeginGetPublicKeyCredentialOption -> {
  // ... other logic

  populatePasskeyData(
    origin,
    option,
    responseBuilder,
    autoSelectEnabled,
    allowedAuthenticator
  )

  // ... other logic as needed
}

Ähnlich wie bei CreateEntry ist eine BiometricPromptData-Instanz auf den Wert PublicKeyCredentialEntry-Instanz. Wenn nicht explizit festgelegt, wird für allowedAuthenticator automatisch die Standardeinstellung verwendet: BIOMETRIC_WEAK.

PublicKeyCredentialEntry(
  // other properties...

  biometricPromptData = BiometricPromptData(
    allowedAuthenticators = allowedAuthenticator
  )
)

Auswahl von Anmeldedateneinträgen verarbeiten

bei der Auswahl der Anmeldedateneinträge für die Passkey-Erstellung oder Passkey-Auswahl bei der Anmeldung, ruf die PendingIntentHandler's retrieveProviderCreateCredentialRequest an oder retrieveProviderGetCredentialRequest. Diese Rückgabeobjekte die die für den Anbieter erforderlichen Metadaten enthalten. Wenn Sie beispielsweise die Auswahl des Eintrags für die Passkey-Erstellung verarbeiten, aktualisieren Sie den 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.authenitcationError
    // Process the error
}

  // Other logic...
}

Dieses Beispiel enthält Informationen zum Erfolg des biometrischen Flusses. Außerdem weitere Informationen zum Berechtigungsnachweis enthält. Wenn der Ablauf fehlschlägt, verwenden Sie die Methode unter biometricPromptResult.authenticationError, um Entscheidungen zu treffen. Die im Rahmen von biometricPromptResult.authenticationError.errorCode sind dieselben Fehlercodes die in der androidx.biometric-Bibliothek definiert sind, androidx.biometric.BiometricPrompt.NO_SPACE androidx.biometric.BiometricPrompt.UNABLE_TO_PROCESS androidx.biometric.BiometricPrompt.ERROR_TIMEOUT und Ähnliches. Die authenticationError enthält auch eine Fehlermeldung in Verbindung mit dem errorCode, das auf einer UI angezeigt werden kann.

Extrahieren Sie auf ähnliche Weise Metadaten während der retrieveProviderGetCredentialRequest. Prüfe, ob dein biometrischer Blutfluss null ist. Falls ja, konfiguriere deine eigenen biometrischen Daten, authentifizieren. Das entspricht der Instrumentierung des Abrufvorgangs:

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.authenitcationError
    // Process the error
}

  // Other logic...