دمج ميزة إنشاء مفتاح مرور بنقرة واحدة وتسجيل الدخول مع إشعارات المقاييس الحيوية

في نظام التشغيل Android 15، يتيح "مدير بيانات الاعتماد" إمكانية إنشاء بيانات الاعتماد واستردادها بنقرة واحدة. في هذا المسار، يتم عرض معلومات بيانات الاعتماد التي يتم إنشاؤها أو استخدامها مباشرةً في طلب المصادقة باستخدام المقاييس الحيوية، بالإضافة إلى نقطة دخول إلى المزيد من الخيارات. تتيح هذه العملية المبسّطة إنشاء بيانات الاعتماد واستردادها بشكل أكثر كفاءة وسلاسة.

المتطلبات:

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

تفعيل ميزة "نقرة واحدة" في خطوات إنشاء مفتاح المرور

تتطابق خطوات إنشاء هذه الطريقة مع عملية إنشاء بيانات الاعتماد الحالية. في BeginCreatePublicKeyCredentialRequest، استخدِم handleCreatePasskeyQuery() لمعالجة الطلب إذا كان يتعلق بمفتاح مرور.

is BeginCreatePublicKeyCredentialRequest -> {
    Log.i(TAG, "Request is passkey type")
    return handleCreatePasskeyQuery(request, passwordCount, passkeyCount)
}

في handleCreatePasskeyQuery()، أدرِج BiometricPromptData مع الفئة CreateEntry:

val createEntry = CreateEntry(
    // Additional properties...
    biometricPromptData = BiometricPromptData(
        allowedAuthenticators = allowedAuthenticator
    ),
)

على مقدّمي بيانات الاعتماد ضبط السمة allowedAuthenticator بشكل صريح في عنصر BiometricPromptData. إذا لم يتم ضبط هذه السمة، ستكون القيمة التلقائية DEVICE_WEAK. اضبط السمة الاختيارية cryptoObject إذا لزم الأمر لحالة الاستخدام.

تفعيل ميزة "نقرة واحدة" في تدفقات مفاتيح المرور لتسجيل الدخول

وكما هو الحال في عملية إنشاء مفتاح المرور، سيتم اتّباع عملية الإعداد الحالية للتعامل مع تسجيل دخول المستخدم. ضِمن BeginGetPublicKeyCredentialOption، استخدِم populatePasskeyData() لجمع المعلومات ذات الصلة بطلب المصادقة:

is BeginGetPublicKeyCredentialOption -> {
    // ... other logic

    populatePasskeyData(
        origin,
        option,
        responseBuilder,
        autoSelectEnabled,
        allowedAuthenticator
    )

    // ... other logic as needed
}

على غرار CreateEntry، يتم ضبط مثيل BiometricPromptData على مثيل PublicKeyCredentialEntry. إذا لم يتم ضبطها بشكلٍ صريح، تكون القيمة التلقائية allowedAuthenticator هي BIOMETRIC_WEAK.

PublicKeyCredentialEntry(
    // other properties...

    biometricPromptData = BiometricPromptData(
        allowedAuthenticators = allowedAuthenticator
    )
)

التعامل مع اختيار إدخال بيانات الاعتماد

أثناء التعامل مع اختيار إدخال بيانات الاعتماد من أجل إنشاء مفتاح مرور أو اختيار مفتاح مرور أثناء تسجيل الدخول، استدعِ الدالة PendingIntentHandler's retrieveProviderCreateCredentialRequest أو retrieveProviderGetCredentialRequest، حسب الاقتضاء. تعرض هذه العناصر بيانات وصفية يحتاجها مقدّم الخدمة. على سبيل المثال، عند التعامل مع اختيار إدخال إنشاء مفتاح مرور، عدِّل الرمز البرمجي على النحو التالي:

val createRequest = PendingIntentHandler.retrieveProviderCreateCredentialRequest(intent)
if (createRequest == null) {
    Log.i(TAG, "request is null")
    setUpFailureResponseAndFinish("Unable to extract request from intent")
    return
}
// Other logic...

val biometricPromptResult = createRequest.biometricPromptResult

// Add your logic based on what needs to be done
// after getting biometrics

if (createRequest.callingRequest is CreatePublicKeyCredentialRequest) {
    val publicKeyRequest: CreatePublicKeyCredentialRequest =
        createRequest.callingRequest as CreatePublicKeyCredentialRequest

    if (biometricPromptResult == null) {
        // Do your own authentication flow, if needed
    }
    else if (biometricPromptResult.isSuccessful) {
        createPasskey(
            publicKeyRequest.requestJson,
            createRequest.callingAppInfo,
            publicKeyRequest.clientDataHash,
            accountId
        )
    } else {
        val error = biometricPromptResult.authenticationError
        // Process the error
    }

    // Other logic...
}

يحتوي هذا المثال على معلومات حول نجاح عملية المصادقة البيومترية. وتتضمّن أيضًا معلومات أخرى حول بيانات الاعتماد. في حال تعذّر تنفيذ العملية، استخدِم رمز الخطأ ضمن biometricPromptResult.authenticationError لاتّخاذ القرارات. رموز الخطأ التي يتم عرضها كجزء من biometricPromptResult.authenticationError.errorCode هي رموز الخطأ نفسها المحدّدة في مكتبة androidx.biometric، مثل androidx.biometric.BiometricPrompt.NO_SPACE و androidx.biometric.BiometricPrompt.UNABLE_TO_PROCESS و androidx.biometric.BiometricPrompt.ERROR_TIMEOUT وما شابه ذلك. سيحتوي authenticationError أيضًا على رسالة خطأ مرتبطة errorCode يمكن عرضها على واجهة مستخدم.

وبالمثل، استخرِج البيانات الوصفية أثناء retrieveProviderGetCredentialRequest. تحقَّق مما إذا كان مسار المقاييس الحيوية هو null. إذا كان الأمر كذلك، اضبط إعدادات المقاييس الحيوية الخاصة بك للمصادقة. يشبه ذلك طريقة إعداد عملية get:

val getRequest =
    PendingIntentHandler.retrieveProviderGetCredentialRequest(intent)

if (getRequest == null) {
    Log.i(TAG, "request is null")
    setUpFailureResponseAndFinish("Unable to extract request from intent")
    return
}

// Other logic...

val biometricPromptResult = getRequest.biometricPromptResult

// Add your logic based on what needs to be done
// after getting biometrics

if (biometricPromptResult == null)
{
    // Do your own authentication flow, if necessary
} else if (biometricPromptResult.isSuccessful) {

    Log.i(TAG, "The response from the biometricPromptResult was ${biometricPromptResult.authenticationResult?.authenticationType}")

    validatePasskey(
        publicKeyRequest.requestJson,
        origin,
        packageName,
        uid,
        passkey.username,
        credId,
        privateKey
    )
} else {
    val error = biometricPromptResult.authenticationError
    // Process the error
}

// Other logic...