A verificação de credenciais digitais em apps Android pode ser usada para autenticar e autorizar a identidade de um usuário (como um documento de identificação oficial), propriedades sobre esse usuário (como uma carteira de habilitação, um diploma acadêmico ou atributos como idade ou endereço) ou outros cenários em que uma credencial precisa ser emitida e verificada para confirmar a autenticidade de uma entidade.
As credenciais digitais são um padrão público do W3C que especifica como acessar as credenciais digitais verificáveis de um usuário em uma carteira digital. Elas são implementadas para casos de uso da Web com a API Credential Management do W3C. No
Android, a API DigitalCredential
do Gerenciador de credenciais é usada para
verificar credenciais digitais.
Implementação
Para verificar credenciais digitais no seu projeto Android, faça o seguinte:
- Adicione dependências ao script de build do app e inicialize uma classe
CredentialManager
. - Construa uma solicitação de credencial digital e use-a para inicializar um
DigitalCredentialOption
, seguido da criação doGetCredentialRequest
. - Inicie o fluxo
getCredential
com a solicitação criada para receber umGetCredentialResponse
bem-sucedido ou processe as exceções que possam ocorrer. Após a recuperação, valide a resposta.
Adicionar dependências e inicializar
Adicione as seguintes dependências ao script de build do Gradle:
dependencies {
implementation("androidx.credentials:credentials:1.6.0-beta01")
implementation("androidx.credentials:credentials-play-services-auth:1.6.0-beta01")
}
Em seguida, inicialize uma instância da classe CredentialManager
.
val credentialManager = CredentialManager.create(context)
Criar uma solicitação de credencial digital
Construa uma solicitação de credencial digital e use-a para inicializar um
DigitalCredentialOption
.
// The request in the JSON format to conform with
// the JSON-ified Credential Manager - Verifier API request definition.
val requestJson = generateRequestFromServer()
val digitalCredentialOption =
GetDigitalCredentialOption(requestJson = requestJson)
// Use the option from the previous step to build the `GetCredentialRequest`.
val getCredRequest = GetCredentialRequest(
listOf(digitalCredentialOption)
)
Confira um exemplo de solicitação OpenId4Vp. Confira uma referência completa neste site.
{
"requests": [
{
"protocol": "openid4vp-v1-unsigned",
"data": {
"response_type": "vp_token",
"response_mode": "dc_api",
"nonce": "OD8eP8BYfr0zyhgq4QCVEGN3m7C1Ht_No9H5fG5KJFk",
"dcql_query": {
"credentials": [
{
"id": "cred1",
"format": "mso_mdoc",
"meta": {
"doctype_value": "org.iso.18013.5.1.mDL"
},
"claims": [
{
"path": [
"org.iso.18013.5.1",
"family_name"
]
},
{
"path": [
"org.iso.18013.5.1",
"given_name"
]
},
{
"path": [
"org.iso.18013.5.1",
"age_over_21"
]
}
]
}
]
}
}
}
]
}
Receber a credencial
Inicie o fluxo getCredential
com a solicitação criada. Você vai receber
um GetCredentialResponse
de sucesso ou um GetCredentialException
se
a solicitação falhar.
O fluxo getCredential
aciona caixas de diálogo do sistema Android para apresentar as opções de credenciais disponíveis ao usuário e coletar a seleção dele. Em seguida, o app de carteira
que contém a opção de credencial escolhida vai mostrar interfaces para coletar consentimento
e realizar as ações necessárias para gerar uma resposta de credencial digital.
coroutineScope.launch {
try {
val result = credentialManager.getCredential(
context = activityContext,
request = getCredRequest
)
verifyResult(result)
} catch (e : GetCredentialException) {
handleFailure(e)
}
}
// Handle the successfully returned credential.
fun verifyResult(result: GetCredentialResponse) {
val credential = result.credential
when (credential) {
is DigitalCredential -> {
val responseJson = credential.credentialJson
validateResponseOnServer(responseJson)
}
else -> {
// Catch any unrecognized credential type here.
Log.e(TAG, "Unexpected type of credential ${credential.type}")
}
}
}
// Handle failure.
fun handleFailure(e: GetCredentialException) {
when (e) {
is GetCredentialCancellationException -> {
// The user intentionally canceled the operation and chose not
// to share the credential.
}
is GetCredentialInterruptedException -> {
// Retry-able error. Consider retrying the call.
}
is NoCredentialException -> {
// No credential was available.
}
is CreateCredentialUnknownException -> {
// An unknown, usually unexpected, error has occurred. Check the
// message error for any additional debugging information.
}
is CreateCredentialCustomException -> {
// You have encountered a custom error thrown by the wallet.
// If you made the API call with a request object that's a
// subclass of CreateCustomCredentialRequest using a 3rd-party SDK,
// then you should check for any custom exception type constants
// within that SDK to match with e.type. Otherwise, drop or log the
// exception.
}
else -> Log.w(TAG, "Unexpected exception type ${e::class.java}")
}
}