La verificación de credenciales digitales en apps para Android se puede usar para autenticar y autorizar la identidad de un usuario (como un documento de identidad gubernamental), las propiedades sobre ese usuario (como una licencia de conducir, un título académico o atributos como la edad o la dirección) o en otros casos en los que se deba emitir y verificar una credencial para confirmar la autenticidad de una entidad.
Las credenciales digitales son un estándar público del W3C que especifica cómo acceder a las credenciales digitales verificables de un usuario desde una billetera digital y se implementan para casos de uso web con la API de Credential Management del W3C. En Android, se usa la API de DigitalCredential
de Credential Manager para verificar las credenciales digitales.
Implementación
Para verificar las credenciales digitales en tu proyecto de Android, haz lo siguiente:
- Agrega dependencias a la secuencia de comandos de compilación de tu app y, luego, inicializa una clase
CredentialManager
. - Construye una solicitud de credencial digital y úsala para inicializar un
DigitalCredentialOption
, y, luego, compila elGetCredentialRequest
. - Inicia el flujo de
getCredential
con la solicitud construida para recibir unGetCredentialResponse
exitoso o controlar las excepciones que puedan ocurrir. Una vez que se recupera correctamente, valida la respuesta.
Agrega dependencias y, luego, inicializa
Agrega las siguientes dependencias a tu secuencia de comandos de compilación de Gradle:
dependencies {
implementation("androidx.credentials:credentials:1.6.0-beta01")
implementation("androidx.credentials:credentials-play-services-auth:1.6.0-beta01")
}
A continuación, inicializa una instancia de la clase CredentialManager
.
val credentialManager = CredentialManager.create(context)
Cómo crear una solicitud de credencial digital
Construye una solicitud de credencial digital y úsala para inicializar un 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)
)
A continuación, se muestra un ejemplo de una solicitud de OpenId4Vp. Puedes encontrar una referencia completa en este sitio web.
{
"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"
]
}
]
}
]
}
}
}
]
}
Obtén la credencial
Inicia el flujo de getCredential
con la solicitud construida. Recibirás un GetCredentialResponse
si la solicitud se realiza correctamente o un GetCredentialException
si falla.
El flujo getCredential
activa diálogos del sistema Android para presentar las opciones de credenciales disponibles del usuario y recopilar su selección. A continuación, la app de la billetera que contiene la opción de credencial elegida mostrará las IU para recopilar el consentimiento y realizar las acciones necesarias para generar una respuesta 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}")
}
}