Intégrer la création et la connexion avec une clé d'accès à un seul geste avec des invites biométriques

Sur Android 15, le Gestionnaire d'identifiants prend en charge un flux en un seul geste pour les identifiants. création et récupération. Dans ce flux, les informations de l'identifiant faisant l'objet ou en cours d'utilisation, s'affiche directement dans la requête biométrique, avec avec un point d'entrée vers plus d'options. Ce processus simplifié crée efficace et rationalisé de création et de récupération d'identifiants.

Conditions requises:

  • Les données biométriques ont été configurées sur l'appareil de l'utilisateur et celui-ci les autorise pour l'authentification dans les applications.
  • Pour les flux de connexion, cette fonctionnalité n'est activée que pour les comptes uniques, même si plusieurs identifiants (comme une clé d'accès et un mot de passe) sont disponibles pour ce compte.

Activer les flux de création de clés d'accès en un seul geste

Les étapes de création de cette méthode correspondent à la création d'identifiants existants processus. Dans votre BeginCreatePublicKeyCredentialRequest, utilisez handleCreatePasskeyQuery() pour traiter la requête s'il s'agit d'une clé d'accès.

is BeginCreatePublicKeyCredentialRequest -> {
  Log.i(TAG, "Request is passkey type")
  return handleCreatePasskeyQuery(request, passwordCount, passkeyCount)
}

Dans votre handleCreatePasskeyQuery(), incluez BiometricPromptData avec la classe CreateEntry:

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

Les fournisseurs d'identifiants doivent définir explicitement la propriété allowedAuthenticator dans l'instance BiometricPromptData. Si cette propriété n'est pas définie, la valeur la valeur par défaut est DEVICE_WEAK. Définissez la propriété facultative cryptoObject si nécessaire. pour votre cas d'utilisation.

Activer l'appui unique sur les flux de clés d'accès de connexion

Comme pour le flux de création de clés d'accès, il suivra la configuration existante pour gérer la connexion des utilisateurs. Sous BeginGetPublicKeyCredentialOption, utilisez populatePasskeyData() pour recueillir les informations pertinentes requête d'authentification:

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

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

  // ... other logic as needed
}

Comme pour CreateEntry, une instance BiometricPromptData est définie sur la PublicKeyCredentialEntry. S'il n'est pas défini explicitement, Valeur par défaut de allowedAuthenticator : BIOMETRIC_WEAK.

PublicKeyCredentialEntry(
  // other properties...

  biometricPromptData = BiometricPromptData(
    allowedAuthenticators = allowedAuthenticator
  )
)

Gérer la sélection des entrées d'identifiants

Lors de la sélection des entrées d'identifiants pour la création de clés d'accès ou la sélection d'une clé d'accès lors de la connexion, appelez le PendingIntentHandler's retrieveProviderCreateCredentialRequest, ou retrieveProviderGetCredentialRequest, le cas échéant. Ils renvoient des objets qui contiennent les métadonnées nécessaires au fournisseur. Par exemple, lorsque vous manipulez sélection de l'entrée pour créer une clé d'accès, mettez à jour votre code comme suit:

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

Cet exemple contient des informations sur la réussite du flux biométrique. Il y a aussi contient d'autres informations sur le jeu d'identification. Si le flux échoue, utilisez la code d'erreur sous biometricPromptResult.authenticationError pour prendre des décisions. Les codes d'erreur renvoyés dans biometricPromptResult.authenticationError.errorCode sont les mêmes que ceux définis dans la bibliothèque androidx.biometric, tels que androidx.biometric.BiometricPrompt.NO_SPACE, androidx.biometric.BiometricPrompt.UNABLE_TO_PROCESS, androidx.biometric.BiometricPrompt.ERROR_TIMEOUT, etc. La authenticationError contient également un message d'erreur associé au errorCode pouvant s'afficher sur une interface utilisateur.

De même, extrayez les métadonnées pendant retrieveProviderGetCredentialRequest. Vérifiez si votre flux biométrique est null. Si oui, configurez vos propres données biométriques pour vous authentifier. Cette opération est semblable à la manière dont l'opération get est instrumentée:

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