שילוב של יצירת מפתח גישה בהקשה אחת וכניסה לחשבון באמצעות הנחיות ביומטריות

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