ادغام ایجاد گذرکلید و ورود به سیستم با یک تک‌ضرب و با پیام‌واره‌های زیست‌سنجشی

در Android 15،‏ Credential Manager از جریان تک‌ضربه‌ای برای ایجاد و بازیابی اطلاعات کاربری پشتیبانی می‌کند. در این جریان، اطلاعات اعتبارنامه‌ای که درحال ایجاد یا استفاده است مستقیماً در «درخواست زیست‌سنجشی» به‌همراه نقطه ورودی به گزینه‌های بیشتر نمایش داده می‌شود. این فرایند ساده‌شده، فرایند ایجاد و بازیابی اعتبارنامه را کارآمدتر و ساده‌تر می‌کند.

شرایط لازم:

  • داده‌های زیست‌سنجشی در دستگاه کاربر راه‌اندازی شده است و کاربر به آن‌ها اجازه می‌دهد برای اصالت‌سنجی در برنامه‌ها استفاده شوند.
  • برای جریان‌های ورود به سیستم، این ویژگی فقط برای سناریوهای تک‌حسابی فعال است، حتی اگر چندین اعتبارنامه (مانند گذرکلید و گذرواژه) برای آن حساب دردسترس باشد.

فعال کردن تک‌ضرب در جریان‌های ایجاد گذرکلید

مراحل ایجاد این روش با فرایند ایجاد اطلاعات اعتباری موجود مطابقت دارد. در 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.ERROR_NO_SPACE، androidx.biometric.BiometricPrompt.ERROR_UNABLE_TO_PROCESS، androidx.biometric.BiometricPrompt.ERROR_TIMEOUT، و موارد مشابه. authenticationError همچنین حاوی پیام خطای مرتبط با errorCode خواهد بود که می‌تواند در واسط کاربر نمایش داده شود.

به‌طور مشابه، فراداده را درطول retrieveProviderGetCredentialRequest استخراج کنید. بررسی کنید که آیا جریان زیست‌سنجشی شما null است. اگر بله، داده‌های زیست‌سنجشی خودتان را برای اصالت‌سنجی پیکربندی کنید. این شبیه به نحوه ابزاربندی عملیات دریافت است:

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...