Pour recevoir et stocker les identifiants des émetteurs, votre application de titulaire doit gérer les flux d'émission. L'émission d'identifiants peut être déclenchée de deux manières :
- Flux initié par l'émetteur : l'utilisateur déclenche une demande d'émission d'une carte de débit virtuelle à partir d'une application ou d'un site Web de l'émetteur. Par exemple, un site Web peut proposer à ses utilisateurs d'ajouter leur passeport à leur portefeuille. L'émetteur appelle l'API d'émission de Credential Manager pour envoyer une requête d'offre d'identifiant OpenID4VCI. Pour traiter ces requêtes, un titulaire doit d'abord s'intégrer à Credential Manager pour enregistrer ses métadonnées. Credential Manager affiche les options pertinentes parmi lesquelles l'utilisateur peut choisir. Une fois que l'utilisateur a sélectionné une option de titulaire, l'application du titulaire est appelée et peut procéder aux étapes nécessaires pour finaliser l'émission.
- Flux initié par le titulaire : l'utilisateur demande à ajouter une carte de vaccination numérique depuis son application de titulaire. Par exemple, un titulaire peut proposer un bouton "Ajouter votre passeport". Dans ce cas, le titulaire gère sa liste d'émetteurs compatibles et ses métadonnées. Il n'a pas besoin de s'intégrer au Gestionnaire d'identifiants Android pour remplir cette fonction.
Pour en savoir plus sur le fonctionnement des identifiants avec l'API Holder, consultez À propos du stockage des identifiants numériques.
Compatibilité avec les versions d'Android
L'API Holder est compatible avec Android 6 (niveau d'API 23) ou version ultérieure.
Implémentation
Pour utiliser l'API Credential Manager Holder, ajoutez les dépendances suivantes au script de compilation du module de votre application :
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") }
Créer le RegistryManager
Créez une instance RegistryManager et enregistrez-y une requête 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)
}
Le matcher est un fichier binaire WebAssembly (Wasm) qui reçoit le creationOptions défini lors de l'enregistrement et l'offre d'identifiants envoyée par l'émetteur pour déterminer les entrées affichées dans l'UI de Credential Manager. Consultez l'exemple d'application de portefeuille Open Source pour obtenir un exemple de matcher.
Gérer une demande d'émission
Ensuite, le portefeuille doit gérer la sélection d'une option de création d'identifiants par l'utilisateur. Définissez une activité qui écoute le filtre d'intent androidx.credentials.registry.provider.action.CREATE_CREDENTIAL, comme illustré dans l'exemple de portefeuille.
L'intent qui lance l'activité contient la requête de création et l'origine de l'appel, que vous pouvez extraire avec la fonction PendingIntentHandler.retrieveProviderCreateCredentialRequest. L'API renvoie un ProviderCreateCredentialRequest contenant toutes les informations associées à la demande de création. Il se compose de deux éléments clés :
- Application ayant effectué la requête. Vous pouvez le récupérer avec
getCallingAppInfo. - Requête de l'application appelante. Vous pouvez la récupérer avec
getCallingRequest, qui renvoie unCreateCredentialRequest. Si la requête concerne des identifiants numériques, il s'agit d'une instance deCreateDigitalCredentialRequest, qui contient le fichier JSON de la requête d'émission dans la propriétérequestJson. Vous pouvez traiter cela avec l'exemple de code suivant :
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)
}
Attestation des clés
Notez les points suivants concernant l'attestation des clés :
- Lorsque vous générez une attestation de clé, vous pouvez utiliser
BigInteger.toByteArraypour convertir les éléments de clé en clé Web JSON, par exemple. Cette méthode peut parfois ajouter un octet de signe et provoquer une erreur de validation. Dans ce cas, supprimez ces octets avant d'envoyer l'attestation de clé à l'émetteur. - Nous vous recommandons d'utiliser
android_key_attestationcomme type de preuve de clé.
Renvoyer la réponse de création
Une fois que le portefeuille a terminé les étapes nécessaires pour enregistrer l'identifiant, terminez l'activité avec la réponse de l'identifiant :
val resultData = Intent()
PendingIntentHandler.setCreateCredentialResponse(
resultData,
CreateDigitalCredentialResponse(response.responseJson)
)
setResult(RESULT_OK, resultData)
finish()
En cas d'exception, vous pouvez également envoyer l'exception d'identifiant :
val resultData = Intent()
PendingIntentHandler.setCreateCredentialException(
resultData,
CreateCredentialUnknownException() // Configure the proper exception
)
setResult(RESULT_OK, resultData)
finish()
Pour voir un exemple complet de renvoi de la réponse d'identifiant en contexte, consultez l'application exemple.