En Android 15, el Administrador de credenciales admite un flujo de un solo toque para la creación y recuperación de credenciales. En este flujo, la información de la credencial que se está creando o usando se muestra directamente en la solicitud biométrica, junto con un punto de entrada a más opciones. Este proceso simplificado crea un proceso de creación y recuperación de credenciales más eficiente y optimizado.
Requisitos:
- La biometría se configuró en el dispositivo del usuario, y este la permite para la autenticación en las aplicaciones.
- Para los flujos de acceso, esta función solo está habilitada para situaciones de una sola cuenta, incluso si hay varias credenciales (como la llave de acceso y la contraseña) disponibles para esa cuenta.
Habilita el toque único en los flujos de creación de llaves de acceso
Los pasos de creación de este método coinciden con el proceso de creación de credenciales existente. Dentro de tu BeginCreatePublicKeyCredentialRequest, usa handleCreatePasskeyQuery() para procesar la solicitud si es para una llave de acceso.
is BeginCreatePublicKeyCredentialRequest -> {
Log.i(TAG, "Request is passkey type")
return handleCreatePasskeyQuery(request, passwordCount, passkeyCount)
}
En tu handleCreatePasskeyQuery(), incluye BiometricPromptData con
la clase CreateEntry:
val createEntry = CreateEntry(
// Additional properties...
biometricPromptData = BiometricPromptData(
allowedAuthenticators = allowedAuthenticator
),
)
Los proveedores de credenciales deben establecer explícitamente la propiedad allowedAuthenticator en la instancia BiometricPromptData. Si no se establece esta propiedad, el valor predeterminado es DEVICE_WEAK. Configura la propiedad cryptoObject opcional si es necesario para tu caso de uso.
Habilita el toque único en los flujos de llaves de acceso
Al igual que el flujo de creación de llaves de acceso, este seguirá la configuración existente para
controlar el acceso del usuario. En BeginGetPublicKeyCredentialOption, usa populatePasskeyData() para recopilar la información pertinente sobre la solicitud de autenticación:
is BeginGetPublicKeyCredentialOption -> {
// ... other logic
populatePasskeyData(
origin,
option,
responseBuilder,
autoSelectEnabled,
allowedAuthenticator
)
// ... other logic as needed
}
Al igual que CreateEntry, una instancia BiometricPromptData se establece en la instancia PublicKeyCredentialEntry. Si no se establece de forma explícita, el valor predeterminado de allowedAuthenticator es BIOMETRIC_WEAK.
PublicKeyCredentialEntry(
// other properties...
biometricPromptData = BiometricPromptData(
allowedAuthenticators = allowedAuthenticator
)
)
Controla la selección de entradas de credenciales
Mientras controlas la selección de entradas de credenciales para la creación de llaves de acceso o
selección de llaves de acceso durante el acceso, llama a PendingIntentHandler's
retrieveProviderCreateCredentialRequest o
retrieveProviderGetCredentialRequest, según corresponda. Estos objetos de devolución contienen los metadatos necesarios para el proveedor. Por ejemplo, cuando controlas la selección de entradas de creación de llaves de acceso, actualiza tu código de la siguiente manera:
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...
}
Este ejemplo contiene información sobre el éxito del flujo biométrico. También contiene otra información sobre la credencial. Si falla el flujo, usa el código de error en biometricPromptResult.authenticationError para tomar decisiones.
Los códigos de error que se muestran como parte de
biometricPromptResult.authenticationError.errorCode son los mismos códigos de error
definidos en la biblioteca androidx.biometric, como
androidx.biometric.BiometricPrompt.NO_SPACE,
androidx.biometric.BiometricPrompt.UNABLE_TO_PROCESS,
androidx.biometric.BiometricPrompt.ERROR_TIMEOUT y similares. El authenticationError también contendrá un mensaje de error asociado con el errorCode que se puede mostrar en una IU.
Del mismo modo, extrae metadatos durante el retrieveProviderGetCredentialRequest.
Verifica si tu flujo biométrico es null. Si es así, configura tu propia biometría para autenticarte. Esto es similar a la forma en que se instrumenta la operación get:
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...