在 Android 15 上,Credential Manager 支持单次点按凭据的流程 创建和检索。在此流程中,凭据信息 会直接显示在生物识别提示中, 并包含一个指向更多选项的入口点这一经过简化的过程创造了更多 高效简化的凭据创建和检索流程。
要求:
- 用户设备上已设置生物识别,用户允许 身份验证机制。
- 对于登录流程,此功能仅适用于单账号场景,即使该账号有多个凭据(例如通行密钥和密码)也是如此。
启用一键通行密钥创建流程
此方法的创建步骤与现有凭据创建步骤相匹配
过程。在 BeginCreatePublicKeyCredentialRequest
中,如果请求是通行密钥请求,请使用 handleCreatePasskeyQuery()
来处理该请求。
is BeginCreatePublicKeyCredentialRequest -> {
Log.i(TAG, "Request is passkey type")
return handleCreatePasskeyQuery(request, passwordCount, passkeyCount)
}
在您的 handleCreatePasskeyQuery()
中,将 BiometricPromptData
包含
CreateEntry
类:
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
。
同样,在 retrieveProviderGetCredentialRequest
期间提取元数据。
检查您的生物识别流程是否为 null
。如果是,请配置您自己的生物识别信息,以便
身份验证。这与 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.authenitcationError
// Process the error
}
// Other logic...