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

ב-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. אם כן, הגדירו את הנתונים הביומטריים שלכם כדי לבצע אימות. זה דומה לאופן שבו הפעולה 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...