Credential Manager - Verifier API

Verifikasi kredensial digital dalam aplikasi Android dapat digunakan untuk mengautentikasi dan mengotorisasi identitas pengguna (seperti tanda pengenal pemerintah), properti tentang pengguna tersebut (seperti surat izin mengemudi, gelar akademis, atau atribut seperti usia atau alamat), atau skenario lain saat kredensial perlu dikeluarkan dan diverifikasi untuk menegaskan keaslian suatu entitas.

Kredensial Digital adalah standar W3C publik yang menentukan cara mengakses kredensial digital teverifikasi pengguna dari dompet digital, dan diimplementasikan untuk kasus penggunaan web dengan W3C Credential Management API. Di Android, API DigitalCredential Credential Manager digunakan untuk memverifikasi kredensial digital.

Implementasi

Untuk memverifikasi kredensial digital di project Android Anda, lakukan hal berikut:

  1. Tambahkan dependensi ke skrip build aplikasi Anda dan inisialisasi class CredentialManager.
  2. Buat permintaan kredensial digital dan gunakan untuk melakukan inisialisasi DigitalCredentialOption, lalu buat GetCredentialRequest.
  3. Luncurkan alur getCredential dengan permintaan yang dibuat untuk menerima GetCredentialResponse yang berhasil atau menangani pengecualian yang mungkin terjadi. Setelah pengambilan berhasil, validasi respons.

Menambahkan dependensi dan melakukan inisialisasi

Tambahkan dependensi berikut ke skrip build Gradle Anda:

dependencies {
    implementation("androidx.credentials:credentials:1.6.0-beta01")
    implementation("androidx.credentials:credentials-play-services-auth:1.6.0-beta01")
}

Selanjutnya, lakukan inisialisasi instance class CredentialManager.

val credentialManager = CredentialManager.create(context)

Membuat permintaan kredensial digital

Buat permintaan kredensial digital dan gunakan untuk menginisialisasi 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)
)

Berikut adalah contoh permintaan OpenId4Vp. Referensi lengkap dapat ditemukan di situs ini.

{
  "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"
                  ]
                }
              ]
            }
          ]
        }
      }
    }
  ]
}

Mendapatkan kredensial

Luncurkan alur getCredential dengan permintaan yang dibuat. Anda akan menerima GetCredentialResponse yang berhasil, atau GetCredentialException jika permintaan gagal.

Alur getCredential memicu dialog sistem Android untuk menampilkan opsi kredensial yang tersedia bagi pengguna dan mengumpulkan pilihannya. Selanjutnya, aplikasi dompet yang berisi opsi kredensial yang dipilih akan menampilkan UI untuk mengumpulkan izin dan melakukan tindakan yang diperlukan untuk membuat respons kredensial 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}")
    }
}