Para receber e armazenar credenciais de emissores, o app do titular precisa processar os fluxos de emissão. A emissão de credenciais pode ser acionada de duas maneiras:
- Fluxo iniciado pelo emissor: o usuário aciona uma solicitação para emitir um VDC de um aplicativo ou site do emissor. Por exemplo, um site pode oferecer aos usuários a opção de "Adicionar seu passaporte à carteira". O emissor chama a API de emissão do Gerenciador de credenciais para fazer uma solicitação de oferta de credencial OpenID4VCI. Para processar essas solicitações, o titular precisa primeiro se integrar ao Gerenciador de credenciais para registrar os metadados. O Gerenciador de credenciais vai mostrar opções relevantes para o usuário selecionar. Depois que o usuário selecionar uma opção de titular, o app do titular será invocado e poderá prosseguir com as etapas necessárias para concluir a emissão.
- Fluxo iniciado pelo titular: o usuário solicita a adição de um VDC pelo app do titular. Por exemplo, um titular pode oferecer um botão para "Adicionar seu passaporte". Nesse caso, o titular mantém a lista de emissores compatíveis e os metadados. Ele não precisa se integrar ao Gerenciador de credenciais do Android para concluir essa função.
Para mais informações sobre como as credenciais funcionam com a API Holder, consulte Sobre o armazenamento de credenciais digitais.
Compatibilidade com versões do Android
A API Holder pode ser usada no Android 6 (nível 23 da API) e versões mais recentes.
Implementação
Para usar a API Credential Manager Holder, adicione as seguintes dependências ao script de build do módulo do app:
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") }
Criar o RegistryManager
Crie uma instância de RegistryManager e registre uma
solicitação de RegisterCreationOptionsRequest com ela.
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)
}
O matcher é um arquivo binário do WebAssembly (Wasm) que recebe o conjunto
creationOptions durante o registro e a oferta de credencial enviada pelo
emissor para determinar as entradas mostradas na interface do Gerenciador de Credenciais. Consulte
o app de carteira de código aberto para ver um exemplo de correspondência.
Processar uma solicitação de emissão
Em seguida, a carteira precisa processar quando uma opção de criação de credencial é selecionada
pelo usuário. Defina uma atividade que detecte o
filtro de intent androidx.credentials.registry.provider.action.CREATE_CREDENTIAL,
conforme demonstrado na carteira de exemplo.
A intent que inicia a atividade contém a solicitação de criação e a origem da chamada, que podem ser extraídas com a função PendingIntentHandler.retrieveProviderCreateCredentialRequest. A API
retorna um ProviderCreateCredentialRequest que contém todas as informações
associadas à solicitação de criação. Há dois componentes principais:
- O app que fez a solicitação. É possível recuperar isso com
getCallingAppInfo. - A solicitação do app de ligação. É possível recuperá-la com
getCallingRequest, que retorna umCreateCredentialRequest. Se a solicitação for para credenciais digitais, ela será uma instância deCreateDigitalCredentialRequest, que contém o JSON da solicitação de emissão na propriedaderequestJson. É possível processar isso com o seguinte exemplo de código:
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)
}
Atestado de chaves
Observe o seguinte sobre o atestado de chave:
- Ao gerar um atestado de chave, talvez você esteja usando
BigInteger.toByteArraypara converter os materiais de chave em, por exemplo, uma chave da Web JSON. Às vezes, esse método pode adicionar um byte de sinal e causar um erro de validação. Se isso acontecer, remova esses bytes antes de enviar o atestado de chave ao emissor. - Recomendamos usar
android_key_attestationcomo o tipo de prova de chave.
Retornar a resposta de criação
Depois que a carteira concluir as etapas necessárias para salvar a credencial, encerre a atividade com a resposta da credencial:
val resultData = Intent()
PendingIntentHandler.setCreateCredentialResponse(
resultData,
CreateDigitalCredentialResponse(response.responseJson)
)
setResult(RESULT_OK, resultData)
finish()
Se houver uma exceção, você poderá enviar a exceção de credencial de maneira semelhante:
val resultData = Intent()
PendingIntentHandler.setCreateCredentialException(
resultData,
CreateCredentialUnknownException() // Configure the proper exception
)
setResult(RESULT_OK, resultData)
finish()
Para conferir um exemplo completo de como retornar a resposta de credencial no contexto, consulte o app de exemplo.