如需接收和存储来自签发方的凭证,您的持有人应用需要处理签发流程。凭证签发可通过以下两种方式触发:
- 发卡机构发起的流程:用户通过发卡机构应用或网站触发 VDC 签发请求。例如,网站可能会向用户提供“将护照添加到钱包”选项。签发方调用 Credential Manager 签发 API,以发出 OpenID4VCI 凭证邀约请求。如需处理此类请求,持有者必须先与 Credential Manager 集成,以注册其元数据。Credential Manager 将显示相关选项供用户选择。用户选择持有者选项后,系统会调用持有者应用,该应用可以继续执行完成签发所需的步骤。
- 持卡人发起的流程:用户请求从其持卡人应用中添加 VDC。例如,持有者可能会提供“添加护照”按钮。 在这种情况下,持有者会维护其支持的签发者列表和元数据。它无需与 Android Credential Manager 集成即可完成此功能。
如需详细了解凭证如何与 Holder API 搭配使用,请参阅关于存储数字凭证。
Android 版本兼容性
Android 6(API 级别 23)及更高版本支持 Holder API。
实现
如需使用 Credential Manager Holder API,请将以下依赖项添加到应用模块的 build 脚本中:
Groovy
dependencies { // Use to implement credentials registrys implementation "androidx.credentials.registry:registry-digitalcredentials-mdoc:1.0.0-alpha04" implementation "androidx.credentials.registry:registry-digitalcredentials-openid:1.0.0-alpha04" implementation "androidx.credentials.registry:registry-digitalcredentials-sdjwtvc:1.0.0-alpha04" implementation "androidx.credentials.registry:registry-provider:1.0.0-alpha04" implementation "androidx.credentials.registry:registry-provider-play-services:1.0.0-alpha04" }
Kotlin
dependencies { // Use to implement credentials registrys implementation("androidx.credentials.registry:registry-digitalcredentials-mdoc:1.0.0-alpha04") implementation("androidx.credentials.registry:registry-digitalcredentials-openid:1.0.0-alpha04") implementation("androidx.credentials.registry:registry-digitalcredentials-sdjwtvc:1.0.0-alpha04") implementation("androidx.credentials.registry:registry-provider:1.0.0-alpha04") implementation("androidx.credentials.registry:registry-provider-play-services:1.0.0-alpha04") }
创建 RegistryManager
创建一个 RegistryManager 实例,并向其注册 RegisterCreationOptionsRequest 请求。
val registryManager = RegistryManager.create(context)
try {
registryManager.registerCreationOptions(object :
RegisterCreationOptionsRequest(
creationOptions = buildIssuanceData(),
matcher = loadIssuanceMatcher(),
type = DigitalCredential.TYPE_DIGITAL_CREDENTIAL,
id = "openid4vci",
) {}
)
} catch (e: Exception) {
Log.e(TAG, "Issuance registration failed.", e)
}
匹配器是一个 WebAssembly (Wasm) 二进制文件,它会接收注册期间设置的 creationOptions 以及签发者发送的凭证邀约,以确定要在 Credential Manager 界面上显示的条目。如需查看匹配器示例,请参阅开源示例钱包应用。
处理签发请求
接下来,钱包需要处理用户选择凭证创建选项的情况。定义一个监听 androidx.credentials.registry.provider.action.CREATE_CREDENTIAL intent 过滤器的 activity,如示例钱包中所示。
启动 activity 的 intent 包含创建请求和调用来源,您可以使用 PendingIntentHandler.retrieveProviderCreateCredentialRequest 函数提取这些信息。API 会返回一个 ProviderCreateCredentialRequest,其中包含与创建请求关联的所有信息。有两个关键组成部分:
- 发出请求的应用。您可以使用
getCallingAppInfo检索此信息。 - 来自调用应用的请求。您可以使用
getCallingRequest检索此请求,该方法会返回CreateCredentialRequest。如果请求是针对数字凭证,则它是CreateDigitalCredentialRequest的实例,其中包含requestJson属性中的签发请求 JSON。您可以使用以下示例代码进行处理:
val pendingIntentRequest =
PendingIntentHandler.retrieveProviderCreateCredentialRequest(intent)
val request = pendingIntentRequest!!.callingRequest
if (request is CreateDigitalCredentialRequest) {
Log.i(TAG, "Got DC creation request: ${request.requestJson}")
processCreationRequest(request.requestJson)
}
密钥认证
关于密钥认证,请注意以下事项:
- 生成密钥认证时,您可能会使用
BigInteger.toByteArray将密钥材料转换为 JSON Web 密钥等。此方法有时可能会添加符号字节并导致验证错误。如果发生这种情况,请先移除这些字节,然后再将密钥认证发送给签发方。 - 我们建议使用
android_key_attestation作为密钥证明类型。
返回创建响应
钱包完成保存凭证所需的步骤后,使用凭证响应完成 activity:
val resultData = Intent()
PendingIntentHandler.setCreateCredentialResponse(
resultData,
CreateDigitalCredentialResponse(response.responseJson)
)
setResult(RESULT_OK, resultData)
finish()
如果出现异常,您也可以类似地发送凭据异常:
val resultData = Intent()
PendingIntentHandler.setCreateCredentialException(
resultData,
CreateCredentialUnknownException() // Configure the proper exception
)
setResult(RESULT_OK, resultData)
finish()
如需查看在上下文中返回凭据响应的完整示例,请参阅示例应用。