在 Android 15 中,凭据管理器支持单点触控流程来创建和检索凭据。在此流程中,正在创建或正在使用的凭据的信息将直接显示在生物识别提示中,以及进入更多选项的入口点。此简化流程创建了一个更高效且简化的凭据创建和检索流程。
要求
- 用户设备上已设置生物识别功能,并且用户允许其用于对应用进行身份验证。
- 对于登录流程,此功能仅在单帐户场景中启用,即使该帐户有多个可用的凭据(例如密码通行密钥和密码)。
启用密码通行密钥创建流程的单点触控
此方法的创建步骤与现有的凭据创建流程匹配。在您的 BeginCreatePublicKeyCredentialRequest
中,如果请求是针对密码通行密钥的,则使用 handleCreatePasskeyQuery()
处理请求。
is BeginCreatePublicKeyCredentialRequest -> {
Log.i(TAG, "Request is passkey type")
return handleCreatePasskeyQuery(request, passwordCount, passkeyCount)
}
在您的 handleCreatePasskeyQuery()
中,包含带有 CreateEntry
类的BiometricPromptData
val createEntry = CreateEntry(
// Additional properties...
biometricPromptData = BiometricPromptData(
allowedAuthenticators = allowedAuthenticator
)
)
凭据提供商应在 BiometricPromptData
实例中显式设置 allowedAuthenticator
属性。如果未设置此属性,则该值默认为 DEVICE_WEAK
。如果您的用例需要,请设置可选的 cryptoObject
属性。
启用登录密码通行密钥流程的单点触控
与密码通行密钥创建流程类似,这将遵循处理用户登录的现有设置。在 BeginGetPublicKeyCredentialOption
下,使用 populatePasskeyData()
收集有关身份验证请求的相关信息
is BeginGetPublicKeyCredentialOption -> {
// ... other logic
populatePasskeyData(
origin,
option,
responseBuilder,
autoSelectEnabled,
allowedAuthenticator
)
// ... other logic as needed
}
与 CreateEntry
类似,BiometricPromptData
实例设置为 PublicKeyCredentialEntry
实例。如果未显式设置,allowedAuthenticator
默认为 BIOMETRIC_WEAK
。
PublicKeyCredentialEntry(
// other properties...
biometricPromptData = BiometricPromptData(
allowedAuthenticators = allowedAuthenticator
)
)
处理凭据条目选择
在处理密钥创建或登录期间密钥选择的凭据输入选择时,请根据需要调用PendingIntentHandler's retrieveProviderCreateCredentialRequest
或retrieveProviderGetCredentialRequest
。这些返回的对象包含提供程序所需的元数据。例如,在处理密钥创建输入选择时,请按如下所示更新您的代码
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...
}
此示例包含有关生物识别流程成功的信息。它还包含有关凭据的其他信息。如果流程失败,请使用biometricPromptResult.authenticationError
下的错误代码进行决策。作为biometricPromptResult.authenticationError.errorCode
一部分返回的错误代码与androidx.biometric库中定义的错误代码相同,例如androidx.biometric.BiometricPrompt.NO_SPACE、androidx.biometric.BiometricPrompt.UNABLE_TO_PROCESS、androidx.biometric.BiometricPrompt.ERROR_TIMEOUT等。authenticationError
还将包含与errorCode
关联的错误消息,该消息可以显示在UI上。
类似地,在retrieveProviderGetCredentialRequest
期间提取元数据。检查您的生物识别流程是否为null
。如果是,请配置您自己的生物识别信息进行身份验证。这类似于获取操作的检测方式
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...