Credential Manager - Verifier API

يمكن استخدام ميزة التحقّق من بيانات الاعتماد الرقمية في تطبيقات Android لمصادقة هوية المستخدم (مثل بطاقة تعريف الهوية الصادرة عن جهة حكومية) والتحقّق منها، أو التحقّق من خصائص هذا المستخدم (مثل رخصة القيادة أو الشهادة الأكاديمية أو السمات مثل العمر أو العنوان)، أو في سيناريوهات أخرى يجب فيها إصدار بيانات اعتماد والتحقّق منها للتأكّد من صحة كيان معيّن.

‫Digital Credentials هو معيار علني صادر عن W3C يحدّد كيفية الوصول إلى بيانات الاعتماد الرقمية القابلة للتحقّق الخاصة بالمستخدم من محفظة رقمية، ويتم تنفيذه لحالات استخدام الويب باستخدام W3C Credential Management API. على Android، يتم استخدام واجهة برمجة التطبيقات DigitalCredential في Credential Manager للتحقّق من بيانات الاعتماد الرقمية.

التوافق مع إصدارات Android

تتوفّر Verifier API على Android 6 (المستوى 23 من واجهة برمجة التطبيقات) والإصدارات الأحدث.

التنفيذ

للتحقّق من بيانات الاعتماد الرقمية في مشروع Android، اتّبِع الخطوات التالية:

  1. أضِف التبعيات إلى نص الإصدار في تطبيقك وأنشِئ فئة CredentialManager.
  2. أنشِئ طلب بيانات اعتماد رقمية واستخدِمه لتهيئة DigitalCredentialOption، ثم أنشِئ GetCredentialRequest.
  3. ابدأ مسار getCredential باستخدام الطلب الذي تم إنشاؤه لتلقّي GetCredentialResponse ناجح أو معالجة أي استثناءات قد تحدث. بعد استرداد الردّ بنجاح، تحقَّق من صحته.

إضافة التبعيات والتهيئة

أضِف التبعيات التالية إلى نص إصدار Gradle:

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

بعد ذلك، أنشِئ مثيلاً لفئة CredentialManager.

val credentialManager = CredentialManager.create(context)

إنشاء طلب بيانات اعتماد رقمية

أنشِئ طلب بيانات اعتماد رقمية واستخدِمه لتهيئة 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)
)

في ما يلي مثال على طلب OpenId4Vp. يمكنك الاطّلاع على مرجع كامل على هذا الموقع الإلكتروني.

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

الحصول على بيانات الاعتماد

ابدأ مسار getCredential باستخدام الطلب الذي تم إنشاؤه. ستتلقّى إما GetCredentialResponse ناجحًا أو GetCredentialException إذا تعذّر تنفيذ الطلب.

يؤدي مسار getCredential إلى ظهور مربّعات حوار في نظام Android لعرض خيارات بيانات الاعتماد المتاحة للمستخدم وجمع الخيار الذي يختاره. بعد ذلك، سيعرض تطبيق المحفظة الذي يحتوي على خيار بيانات الاعتماد الذي تم اختياره واجهات مستخدم لجمع الموافقة وتنفيذ الإجراءات اللازمة لإنشاء ردّ على بيانات الاعتماد الرقمية.

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}")
    }
}