عرض مربّع حوار المصادقة بالمقاييس الحيوية

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

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

الإفصاح عن أنواع المصادقة التي يتوافق معها تطبيقك

لتحديد أنواع المصادقة التي يتيحها تطبيقك، استخدِم واجهة BiometricManager.Authenticators. يتيح لك النظام الإفصاح عن الأنواع التالية من المصادقة:

BIOMETRIC_STRONG
المصادقة باستخدام ميزة أمان من الفئة 3 مستندة إلى المقاييس الحيوية، على النحو الموضّح في صفحة تعريف توافق Android.
BIOMETRIC_WEAK
المصادقة باستخدام ميزة المقاييس الحيوية من الفئة 2، على النحو المحدّد في صفحة تعريف التوافق مع Android
DEVICE_CREDENTIAL
المصادقة باستخدام بيانات اعتماد قفل الشاشة: رقم التعريف الشخصي أو النقش أو كلمة المرور الخاصة بالمستخدم

لبدء استخدام معرّف الهوية، على المستخدم إنشاء رقم تعريف شخصي أو نقش أو كلمة مرور. إذا لم يكن لدى المستخدم بصمة إصبع مسجَّلة، تطلب منه عملية تسجيل البصمة البيولوجية إنشاء بصمة إصبع.

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

Kotlin

// Lets the user authenticate using either a Class 3 biometric or
// their lock screen credential (PIN, pattern, or password).
promptInfo = BiometricPrompt.PromptInfo.Builder()
        .setTitle("Biometric login for my app")
        .setSubtitle("Log in using your biometric credential")
        .setAllowedAuthenticators(BIOMETRIC_STRONG or DEVICE_CREDENTIAL)
        .build()

Java

// Lets user authenticate using either a Class 3 biometric or
// their lock screen credential (PIN, pattern, or password).
promptInfo = new BiometricPrompt.PromptInfo.Builder()
        .setTitle("Biometric login for my app")
        .setSubtitle("Log in using your biometric credential")
        .setAllowedAuthenticators(BIOMETRIC_STRONG | DEVICE_CREDENTIAL)
        .build();

لا تتوفّر المجموعات التالية من أنواع المصادقة على Android 10 (مستوى واجهة برمجة التطبيقات 29) والإصدارات الأقدم: DEVICE_CREDENTIAL و BIOMETRIC_STRONG | DEVICE_CREDENTIAL. للتحقّق من توفّر رقم تعريف شخصي أو نقش أو كلمة مرور على نظام التشغيل Android 10 والإصدارات الأقدم، استخدِم KeyguardManager.isDeviceSecure() الطريقة.

التأكّد من توفّر المصادقة بالمقاييس الحيوية

بعد تحديد عناصر المصادقة التي يتيحها تطبيقك، تحقّق مما إذا كانت هذه العناصر متاحة. لإجراء ذلك، عليك تمرير التركيبة الثنائية نفسها للأنواع التي أعلنت عنها باستخدام الأسلوب setAllowedAuthenticators() إلى الأسلوب canAuthenticate(). إذا لزم الأمر، استخدِم الإجراء ACTION_BIOMETRIC_ENROLL للنوايا. في سمة intent extra، قدِّم مجموعة مصادقة يقبلها تطبيقك. يطلب هذا الإجراء من المستخدم تسجيل بيانات الاعتماد لجهاز مصادقة يقبله تطبيقك.

Kotlin

val biometricManager = BiometricManager.from(this)
when (biometricManager.canAuthenticate(BIOMETRIC_STRONG or DEVICE_CREDENTIAL)) {
    BiometricManager.BIOMETRIC_SUCCESS ->
        Log.d("MY_APP_TAG", "App can authenticate using biometrics.")
    BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE ->
        Log.e("MY_APP_TAG", "No biometric features available on this device.")
    BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE ->
        Log.e("MY_APP_TAG", "Biometric features are currently unavailable.")
    BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED -> {
        // Prompts the user to create credentials that your app accepts.
        val enrollIntent = Intent(Settings.ACTION_BIOMETRIC_ENROLL).apply {
            putExtra(Settings.EXTRA_BIOMETRIC_AUTHENTICATORS_ALLOWED,
                BIOMETRIC_STRONG or DEVICE_CREDENTIAL)
        }
        startActivityForResult(enrollIntent, REQUEST_CODE)
    }
}

Java

BiometricManager biometricManager = BiometricManager.from(this);
switch (biometricManager.canAuthenticate(BIOMETRIC_STRONG | DEVICE_CREDENTIAL)) {
    case BiometricManager.BIOMETRIC_SUCCESS:
        Log.d("MY_APP_TAG", "App can authenticate using biometrics.");
        break;
    case BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE:
        Log.e("MY_APP_TAG", "No biometric features available on this device.");
        break;
    case BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE:
        Log.e("MY_APP_TAG", "Biometric features are currently unavailable.");
        break;
    case BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED:
        // Prompts the user to create credentials that your app accepts.
        final Intent enrollIntent = new Intent(Settings.ACTION_BIOMETRIC_ENROLL);
        enrollIntent.putExtra(Settings.EXTRA_BIOMETRIC_AUTHENTICATORS_ALLOWED,
                BIOMETRIC_STRONG | DEVICE_CREDENTIAL);
        startActivityForResult(enrollIntent, REQUEST_CODE);
        break;
}

تحديد كيفية مصادقة المستخدم

بعد مصادقة المستخدم، يمكنك التحقّق مما إذا كان المستخدم قد تمّت مصادقة باستخدام بيانات اعتماد الجهاز أو بيانات اعتماد المقاييس الحيوية من خلال الاتصال بالرقم getAuthenticationType().

عرض إشعار طلب تسجيل الدخول

لعرض طلب من النظام يطلب من المستخدم المصادقة باستخدام بيانات الاعتماد الحيوية، استخدِم مكتبة المقاييس الحيوية. إنّ مربّع الحوار الذي يقدّمه النظام متّسق في جميع التطبيقات التي تستخدمه، ما يمنح المستخدمين تجربة استخدام أكثر موثوقية. يظهر مثال على مربّع الحوار في الشكل 1.

لقطة شاشة تعرض مربّع حوار
الشكل 1. مربّع حوار النظام يطلب مصادقة بالمقاييس الحيوية

لإضافة مصادقة بالمقاييس الحيوية إلى تطبيقك باستخدام مكتبة المقاييس الحيوية، أكمِل الخطوات التالية:

  1. في ملف build.gradle الخاص بوحدة التطبيق، أضِف تبعية على مكتبة androidx.biometric.

  2. في النشاط أو المقتطف الذي يستضيف مربّع حوار تسجيل الدخول باستخدام المقاييس الحيوية، اعرض مربّع الحوار باستخدام المنطق الموضَّح في مقتطف الرمز التالي:

    Kotlin

    private lateinit var executor: Executor
    private lateinit var biometricPrompt: BiometricPrompt
    private lateinit var promptInfo: BiometricPrompt.PromptInfo
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_login)
        executor = ContextCompat.getMainExecutor(this)
        biometricPrompt = BiometricPrompt(this, executor,
                object : BiometricPrompt.AuthenticationCallback() {
            override fun onAuthenticationError(errorCode: Int,
                    errString: CharSequence) {
                super.onAuthenticationError(errorCode, errString)
                Toast.makeText(applicationContext,
                    "Authentication error: $errString", Toast.LENGTH_SHORT)
                    .show()
            }
    
            override fun onAuthenticationSucceeded(
                    result: BiometricPrompt.AuthenticationResult) {
                super.onAuthenticationSucceeded(result)
                Toast.makeText(applicationContext,
                    "Authentication succeeded!", Toast.LENGTH_SHORT)
                    .show()
            }
    
            override fun onAuthenticationFailed() {
                super.onAuthenticationFailed()
                Toast.makeText(applicationContext, "Authentication failed",
                    Toast.LENGTH_SHORT)
                    .show()
            }
        })
    
        promptInfo = BiometricPrompt.PromptInfo.Builder()
                .setTitle("Biometric login for my app")
                .setSubtitle("Log in using your biometric credential")
                .setNegativeButtonText("Use account password")
                .build()
    
        // Prompt appears when user clicks "Log in".
        // Consider integrating with the keystore to unlock cryptographic operations,
        // if needed by your app.
        val biometricLoginButton =
                findViewById<Button>(R.id.biometric_login)
        biometricLoginButton.setOnClickListener {
            biometricPrompt.authenticate(promptInfo)
        }
    }
    

    Java

    private Executor executor;
    private BiometricPrompt biometricPrompt;
    private BiometricPrompt.PromptInfo promptInfo;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        executor = ContextCompat.getMainExecutor(this);
        biometricPrompt = new BiometricPrompt(MainActivity.this,
                executor, new BiometricPrompt.AuthenticationCallback() {
            @Override
            public void onAuthenticationError(int errorCode,
                    @NonNull CharSequence errString) {
                super.onAuthenticationError(errorCode, errString);
                Toast.makeText(getApplicationContext(),
                    "Authentication error: " + errString, Toast.LENGTH_SHORT)
                    .show();
            }
    
            @Override
            public void onAuthenticationSucceeded(
                    @NonNull BiometricPrompt.AuthenticationResult result) {
                super.onAuthenticationSucceeded(result);
                Toast.makeText(getApplicationContext(),
                    "Authentication succeeded!", Toast.LENGTH_SHORT).show();
            }
    
            @Override
            public void onAuthenticationFailed() {
                super.onAuthenticationFailed();
                Toast.makeText(getApplicationContext(), "Authentication failed",
                    Toast.LENGTH_SHORT)
                    .show();
            }
        });
    
        promptInfo = new BiometricPrompt.PromptInfo.Builder()
                .setTitle("Biometric login for my app")
                .setSubtitle("Log in using your biometric credential")
                .setNegativeButtonText("Use account password")
                .build();
    
        // Prompt appears when user clicks "Log in".
        // Consider integrating with the keystore to unlock cryptographic operations,
        // if needed by your app.
        Button biometricLoginButton = findViewById(R.id.biometric_login);
        biometricLoginButton.setOnClickListener(view -> {
                biometricPrompt.authenticate(promptInfo);
        });
    }
    

استخدام حلّ تشفير يعتمد على المصادقة

لتعزيز حماية المعلومات الحسّاسة في تطبيقك، يمكنك دمج التشفير في سير عمل المصادقة باستخدام المقاييس الحيوية باستخدام مثيل CryptoObject. يتيح إطار العمل العناصر التشفيرية التالية: Signature، Cipher، Mac.

بعد مصادقة المستخدم بنجاح باستخدام طلب معلومات حيوية، يمكن لتطبيقك تنفيذ عملية تشفير. على سبيل المثال، إذا كنت تُجري مصادقة باستخدام عنصر Cipher، يمكن لتطبيقك بعد ذلك إجراء التشفير وفك التشفير باستخدام عنصر SecretKey.

تتناول الأقسام التالية أمثلة على استخدام عنصر Cipher وSecretKey لتشفير البيانات. يستخدِم كل مثال الخطوات التالية:

Kotlin

private fun generateSecretKey(keyGenParameterSpec: KeyGenParameterSpec) {
    val keyGenerator = KeyGenerator.getInstance(
            KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore")
    keyGenerator.init(keyGenParameterSpec)
    keyGenerator.generateKey()
}

private fun getSecretKey(): SecretKey {
    val keyStore = KeyStore.getInstance("AndroidKeyStore")

    // Before the keystore can be accessed, it must be loaded.
    keyStore.load(null)
    return keyStore.getKey(KEY_NAME, null) as SecretKey
}

private fun getCipher(): Cipher {
    return Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
            + KeyProperties.BLOCK_MODE_CBC + "/"
            + KeyProperties.ENCRYPTION_PADDING_PKCS7)
}

Java

private void generateSecretKey(KeyGenParameterSpec keyGenParameterSpec) {
    KeyGenerator keyGenerator = KeyGenerator.getInstance(
            KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
    keyGenerator.init(keyGenParameterSpec);
    keyGenerator.generateKey();
}

private SecretKey getSecretKey() {
    KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");

    // Before the keystore can be accessed, it must be loaded.
    keyStore.load(null);
    return ((SecretKey)keyStore.getKey(KEY_NAME, null));
}

private Cipher getCipher() {
    return Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
            + KeyProperties.BLOCK_MODE_CBC + "/"
            + KeyProperties.ENCRYPTION_PADDING_PKCS7);
}

المصادقة باستخدام بيانات الاعتماد الحيوية فقط

إذا كان تطبيقك يستخدم مفتاحًا سريًا يتطلّب بيانات اعتماد المقاييس الحيوية لفتح القفل، على المستخدم مصادقة بيانات اعتماد المقاييس الحيوية في كل مرة قبل أن يصل تطبيقك إلى المفتاح.

لتشفير المعلومات الحسّاسة فقط بعد مصادقة المستخدم باستخدام مستندات اعتماد مستندة إلى البصمات الحيوية، يُرجى إكمال الخطوات التالية:

  1. أنشئ مفتاحًا يستخدم الإعداد التالي KeyGenParameterSpec:

    Kotlin

    generateSecretKey(KeyGenParameterSpec.Builder(
            KEY_NAME,
            KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT)
            .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
            .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
            .setUserAuthenticationRequired(true)
            // Invalidate the keys if the user has registered a new biometric
            // credential, such as a new fingerprint. Can call this method only
            // on Android 7.0 (API level 24) or higher. The variable
            // "invalidatedByBiometricEnrollment" is true by default.
            .setInvalidatedByBiometricEnrollment(true)
            .build())
    

    Java

    generateSecretKey(new KeyGenParameterSpec.Builder(
            KEY_NAME,
            KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
            .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
            .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
            .setUserAuthenticationRequired(true)
            // Invalidate the keys if the user has registered a new biometric
            // credential, such as a new fingerprint. Can call this method only
            // on Android 7.0 (API level 24) or higher. The variable
            // "invalidatedByBiometricEnrollment" is true by default.
            .setInvalidatedByBiometricEnrollment(true)
            .build());
    
  2. ابدأ سير عمل المصادقة بالمقاييس الحيوية الذي يتضمّن ترميزًا:

    Kotlin

    biometricLoginButton.setOnClickListener {
        // Exceptions are unhandled within this snippet.
        val cipher = getCipher()
        val secretKey = getSecretKey()
        cipher.init(Cipher.ENCRYPT_MODE, secretKey)
        biometricPrompt.authenticate(promptInfo,
                BiometricPrompt.CryptoObject(cipher))
    }
    

    Java

    biometricLoginButton.setOnClickListener(view -> {
        // Exceptions are unhandled within this snippet.
        Cipher cipher = getCipher();
        SecretKey secretKey = getSecretKey();
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        biometricPrompt.authenticate(promptInfo,
                new BiometricPrompt.CryptoObject(cipher));
    });
    
  3. ضمن عمليات الاستدعاء الخاصة بالمصادقة باستخدام المقاييس الحيوية، استخدِم المفتاح السري لتشفير المعلومات الحسّاسة:

    Kotlin

    override fun onAuthenticationSucceeded(
            result: BiometricPrompt.AuthenticationResult) {
        val encryptedInfo: ByteArray = result.cryptoObject.cipher?.doFinal(
            // plaintext-string text is whatever data the developer would like
            // to encrypt. It happens to be plain-text in this example, but it
            // can be anything
                plaintext-string.toByteArray(Charset.defaultCharset())
        )
        Log.d("MY_APP_TAG", "Encrypted information: " +
                Arrays.toString(encryptedInfo))
    }
    

    Java

    @Override
    public void onAuthenticationSucceeded(
            @NonNull BiometricPrompt.AuthenticationResult result) {
        // NullPointerException is unhandled; use Objects.requireNonNull().
        byte[] encryptedInfo = result.getCryptoObject().getCipher().doFinal(
            // plaintext-string text is whatever data the developer would like
            // to encrypt. It happens to be plain-text in this example, but it
            // can be anything
                plaintext-string.getBytes(Charset.defaultCharset()));
        Log.d("MY_APP_TAG", "Encrypted information: " +
                Arrays.toString(encryptedInfo));
    }

المصادقة باستخدام المقاييس الحيوية أو بيانات اعتماد قفل الشاشة

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

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

  1. أنشئ مفتاحًا يستخدم الإعداد التالي KeyGenParameterSpec:

    Kotlin

    generateSecretKey(KeyGenParameterSpec.Builder(
        KEY_NAME,
        KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT)
        .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
        .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
        .setUserAuthenticationRequired(true)
        .setUserAuthenticationParameters(VALIDITY_DURATION_SECONDS,
                ALLOWED_AUTHENTICATORS)
        .build())
    

    Java

    generateSecretKey(new KeyGenParameterSpec.Builder(
        KEY_NAME,
        KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
        .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
        .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
        .setUserAuthenticationRequired(true)
        .setUserAuthenticationParameters(VALIDITY_DURATION_SECONDS,
                ALLOWED_AUTHENTICATORS)
        .build());
    
  2. خلال فترة زمنية تبلغ VALIDITY_DURATION_SECONDS بعد مصادقة المستخدم، يجب تشفير المعلومات الحساسة:

    Kotlin

    private fun encryptSecretInformation() {
        // Exceptions are unhandled for getCipher() and getSecretKey().
        val cipher = getCipher()
        val secretKey = getSecretKey()
        try {
            cipher.init(Cipher.ENCRYPT_MODE, secretKey)
            val encryptedInfo: ByteArray = cipher.doFinal(
                // plaintext-string text is whatever data the developer would
                // like to encrypt. It happens to be plain-text in this example,
                // but it can be anything
                    plaintext-string.toByteArray(Charset.defaultCharset()))
            Log.d("MY_APP_TAG", "Encrypted information: " +
                    Arrays.toString(encryptedInfo))
        } catch (e: InvalidKeyException) {
            Log.e("MY_APP_TAG", "Key is invalid.")
        } catch (e: UserNotAuthenticatedException) {
            Log.d("MY_APP_TAG", "The key's validity timed out.")
            biometricPrompt.authenticate(promptInfo)
        }
    

    Java

    private void encryptSecretInformation() {
        // Exceptions are unhandled for getCipher() and getSecretKey().
        Cipher cipher = getCipher();
        SecretKey secretKey = getSecretKey();
        try {
            // NullPointerException is unhandled; use Objects.requireNonNull().
            ciper.init(Cipher.ENCRYPT_MODE, secretKey);
            byte[] encryptedInfo = cipher.doFinal(
                // plaintext-string text is whatever data the developer would
                // like to encrypt. It happens to be plain-text in this example,
                // but it can be anything
                    plaintext-string.getBytes(Charset.defaultCharset()));
        } catch (InvalidKeyException e) {
            Log.e("MY_APP_TAG", "Key is invalid.");
        } catch (UserNotAuthenticatedException e) {
            Log.d("MY_APP_TAG", "The key's validity timed out.");
            biometricPrompt.authenticate(promptInfo);
        }
    }
    

المصادقة باستخدام مفاتيح المصادقة لكل استخدام

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

لربط عنصر BiometricPrompt بمفتاح مصادقة لكل استخدام، أضِف رمزًا يشبه ما يلي:

Kotlin

val authPerOpKeyGenParameterSpec =
        KeyGenParameterSpec.Builder("myKeystoreAlias", key-purpose)
    // Accept either a biometric credential or a device credential.
    // To accept only one type of credential, include only that type as the
    // second argument.
    .setUserAuthenticationParameters(0 /* duration */,
            KeyProperties.AUTH_BIOMETRIC_STRONG or
            KeyProperties.AUTH_DEVICE_CREDENTIAL)
    .build()

Java

KeyGenParameterSpec authPerOpKeyGenParameterSpec =
        new KeyGenParameterSpec.Builder("myKeystoreAlias", key-purpose)
    // Accept either a biometric credential or a device credential.
    // To accept only one type of credential, include only that type as the
    // second argument.
    .setUserAuthenticationParameters(0 /* duration */,
            KeyProperties.AUTH_BIOMETRIC_STRONG |
            KeyProperties.AUTH_DEVICE_CREDENTIAL)
    .build();

المصادقة بدون إجراء صريح من المستخدم

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

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

يعرض الشكل 2 نسختَين من مربّع الحوار نفسه. يتطلّب أحد الإصدارَين إجراءً صريحًا من المستخدِم، بينما لا يتطلّب الإصدار الآخر ذلك.

لقطة شاشة لمربّع الحوار لقطة شاشة لمربّع الحوار
الشكل 2. ميزة "التعرّف على الوجه" بدون تأكيد المستخدم (أعلى) وتأكيد المستخدم (أسفل)

يوضّح مقتطف الرمز البرمجي التالي كيفية عرض مربّع حوار لا يتطلّب إجراءً صريحًا من المستخدم لإكمال عملية المصادقة:

Kotlin

// Lets the user authenticate without performing an action, such as pressing a
// button, after their biometric credential is accepted.
promptInfo = BiometricPrompt.PromptInfo.Builder()
        .setTitle("Biometric login for my app")
        .setSubtitle("Log in using your biometric credential")
        .setNegativeButtonText("Use account password")
        .setConfirmationRequired(false)
        .build()

Java

// Lets the user authenticate without performing an action, such as pressing a
// button, after their biometric credential is accepted.
promptInfo = new BiometricPrompt.PromptInfo.Builder()
        .setTitle("Biometric login for my app")
        .setSubtitle("Log in using your biometric credential")
        .setNegativeButtonText("Use account password")
        .setConfirmationRequired(false)
        .build();

السماح بالرجوع إلى بيانات الاعتماد غير البيومترية

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

إذا كان تطبيقك يستخدم حاليًا createConfirmDeviceCredentialIntent() أو setDeviceCredentialAllowed() لتوفير هذه الميزة، يمكنك التبديل إلى استخدام setAllowedAuthenticators().

مصادر إضافية

لمزيد من المعلومات عن المصادقة بالمقاييس الحيوية على Android، يمكنك الرجوع إلى المراجع التالية:

مشاركات المدونة