La validation des identifiants numériques dans les applications Android peut être utilisée pour authentifier et autoriser l'identité d'un utilisateur (comme une pièce d'identité officielle), des propriétés de cet utilisateur (comme un permis de conduire, un diplôme universitaire ou des attributs tels que l'âge ou l'adresse), ou d'autres scénarios dans lesquels un identifiant doit être émis et validé pour confirmer l'authenticité d'une entité.
L'API Verifier est compatible avec Android 9 (niveau d'API 28) et versions ultérieures.
Implémentation
Pour vérifier les identifiants numériques dans votre projet Android, procédez comme suit :
- Ajoutez des dépendances au script de compilation de votre application et initialisez une classe
CredentialManager. - Créez une requête d'identifiant numérique et utilisez-la pour initialiser un
DigitalCredentialOption, puis créez leGetCredentialRequest. - Lancez le flux
getCredentialavec la requête construite pour recevoir unGetCredentialResponseréussi ou gérer les exceptions qui pourraient se produire. Une fois la récupération réussie, validez la réponse.
Ajouter des dépendances et initialiser
Ajoutez les dépendances suivantes à votre script de compilation Gradle :
dependencies {
implementation("androidx.credentials:credentials:1.6.0-beta01")
implementation("androidx.credentials:credentials-play-services-auth:1.6.0-beta01")
}
Ensuite, initialisez une instance de la classe CredentialManager.
val credentialManager = CredentialManager.create(context)
Créer une requête d'identifiant numérique
Créez une requête d'identifiant numérique et utilisez-la pour initialiser 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)
)
L'exemple suivant illustre une requête OpenId4Vp1. Pour en savoir plus sur les champs de cette requête, consultez la documentation OpenID.
{
"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"
]
}
]
}
]
}
}
}
]
}
Obtenir la certification
Lancez le flux getCredential avec la requête construite. Vous recevrez un message GetCredentialResponse en cas de réussite ou un message GetCredentialException en cas d'échec de la requête.
Le flux getCredential déclenche des boîtes de dialogue du système Android pour présenter les options d'identifiants disponibles de l'utilisateur et collecter sa sélection. Ensuite, l'application de portefeuille contenant l'option d'identifiant choisie affichera des interfaces utilisateur pour recueillir le consentement et effectuer les actions nécessaires pour générer une réponse d'identifiant numérique.
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.
}
else -> Log.w(TAG, "Unexpected exception type ${e::class.java}")
}
}
Demandes flexibles d'identifiants multiples
L'API Digital Credentials permet également de demander plusieurs types d'identifiants à la fois à l'aide d'OpenID4VP :
- Requêtes simultanées : demandez plusieurs identifiants dans une seule transaction utilisateur. Par exemple, une application de voyage peut demander simultanément une carte d'embarquement et une pièce d'identité officielle, ce qui permet à l'utilisateur de les examiner et de les accepter en un seul geste.
- Traitement flexible : acceptez un ou plusieurs types d'identifiants ou d'émetteurs. Par exemple, un flux de vérification de l'âge peut accepter un permis de conduire ou un passeport, ce qui permet aux utilisateurs de répondre à la demande en utilisant l'un des justificatifs stockés dans leur portefeuille.
Voici un exemple de demande de plusieurs identifiants dans une seule requête :
{
"credentials": [
{
"id": "gov_id1",
"format": "mso_mdoc",
"meta": {
"doctype_value": "org.iso.18013.5.1.mDL"
},
"claims": [
{
"path": [
"org.iso.18013.5.1",
"age_over_21"
]
}
]
},
{
"id": "boarding_pass1",
"format": "dc+sd-jwt",
"meta": {
"vct_values": [
"https://credentials.example.airline/boarding-pass"
]
},
"claims": [
{
"path": [
"flight_number"
]
},
{
"path": [
"seat"
]
}
]
}
]
}
Gérer la réponse
Après avoir effectué la demande d'identifiants, gérez le GetCredentialResponse renvoyé par CredentialManager.
// 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}")
}
}
}
Gérer les exceptions
Votre application doit gérer les erreurs qui peuvent être générées, y compris s'il n'y a pas d'identifiants sur l'appareil ou si l'utilisateur annule l'opération :
// 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}")
}
}