Per ricevere e archiviare le credenziali dagli emittenti, l'app del titolare deve gestire i flussi di emissione. L'emissione delle credenziali può essere attivata in due modi:
- Flusso avviato dall'emittente: l'utente attiva una richiesta di emissione di una VDC da un'applicazione o un sito web dell'emittente. Ad esempio, un sito web può offrire ai suoi utenti l'opzione "Aggiungi il tuo passaporto al tuo wallet". L'emittente chiama l'API di emissione di Gestore delle credenziali per effettuare una richiesta di offerta di credenziali OpenID4VCI. Per gestire queste richieste, un titolare deve prima integrarsi con Gestore delle credenziali per registrare i propri metadati. Gestore delle credenziali mostrerà le opzioni pertinenti che l'utente potrà selezionare. Dopo che l'utente ha selezionato un'opzione di titolare, l'applicazione del titolare verrà richiamata e potrà procedere con i passaggi necessari per completare l'emissione.
- Flusso avviato dal titolare: l'utente richiede di aggiungere una VDC dalla propria applicazione titolare. Ad esempio, un titolare potrebbe offrire un pulsante "Aggiungi il tuo passaporto". In questo caso, il titolare gestisce l'elenco degli emittenti supportati e i metadati. Non è necessario che si integri con Gestore delle credenziali di Android per completare questa funzione.
Per ulteriori informazioni su come funzionano le credenziali con l'API Holder, consulta Informazioni sulla memorizzazione delle credenziali digitali.
Compatibilità con le versioni di Android
L'API Holder è supportata su Android 6 (livello API 23) e versioni successive.
Implementazione
Per utilizzare l'API Holder di Gestore delle credenziali, aggiungi le seguenti dipendenze allo script di build del modulo dell'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") }
Crea RegistryManager
Crea un'istanza RegistryManager e registra una richiesta 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)
}
Il matcher è un file binario WebAssembly (Wasm) che riceve il
creationOptions impostato durante la registrazione e l'offerta di credenziali inviata dall'emittente per determinare le voci visualizzate nell'interfaccia utente di Gestore delle credenziali. Per un esempio di matcher, consulta l'app wallet open source di esempio.
Gestisci una richiesta di emissione
Successivamente, il wallet deve gestire la selezione di un'opzione di creazione delle credenziali da parte dell'utente. Definisci un'attività che ascolta il filtro per intent androidx.credentials.registry.provider.action.CREATE_CREDENTIAL, come mostrato nel wallet di esempio.
L'intent che avvia l'attività contiene la richiesta di creazione e l'origine della chiamata, che puoi estrarre con la funzione PendingIntentHandler.retrieveProviderCreateCredentialRequest. L'API
restituisce un ProviderCreateCredentialRequest contenente tutte le informazioni
associate alla richiesta di creazione. I componenti chiave sono due:
- L'app che ha effettuato la richiesta. Puoi recuperarlo con
getCallingAppInfo. - La richiesta dell'app di chiamate. Puoi recuperarla con
getCallingRequest, che restituisce unCreateCredentialRequest. Se la richiesta riguarda credenziali digitali, si tratta di un'istanza diCreateDigitalCredentialRequest, che contiene il file JSON della richiesta di emissione nella proprietàrequestJson. Puoi elaborarlo con il seguente codice campione:
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)
}
Attestazione di chiavi
Tieni presente quanto segue in merito all'attestazione di chiavi:
- Quando generi un'attestazione di chiavi, potresti utilizzare
BigInteger.toByteArrayper convertire i materiali della chiave, ad esempio, in una chiave web JSON. Questo metodo a volte può aggiungere un byte di segno e causare un errore di convalida. In questo caso, rimuovi questi byte prima di inviare l'attestazione di chiavi all'emittente. - Ti consigliamo di utilizzare
android_key_attestationcome tipo di prova della chiave.
Restituisci la risposta di creazione
Una volta che il wallet ha completato i passaggi necessari per salvare la credenziale, termina l'attività con la risposta della credenziale:
val resultData = Intent()
PendingIntentHandler.setCreateCredentialResponse(
resultData,
CreateDigitalCredentialResponse(response.responseJson)
)
setResult(RESULT_OK, resultData)
finish()
Se si verifica un'eccezione, puoi inviare l'eccezione della credenziale in modo simile:
val resultData = Intent()
PendingIntentHandler.setCreateCredentialException(
resultData,
CreateCredentialUnknownException() // Configure the proper exception
)
setResult(RESULT_OK, resultData)
finish()
Per un esempio completo della restituzione della risposta della credenziale nel contesto, consulta l'app di esempio.