No credentials available while getting credentials from Passkeys

No credentials available while getting credentials from Passkeys

  

I have successfully created a passkey device in Google and created a credential (screen lock) which can be seen in "Password Manager" in "Manage your Google Account".

I use the following code to create the credential.

val createPublicKeyCredentialResponse = CredentialManager
    .create(context)
    .createCredential(
        context = context,
        request = createPublicKeyCredentialRequest,
    )

And the result createPublicKeyCredentialResponse is like:

{
    "rawId": "<rawId>",
    "authenticatorAttachment": "platform",
    "type": "public-key",
    "id": "<id>",
    "response": {
        "clientDataJSON": "<clientDataJSON>",
        "attestationObject": "<attestationObject>",
        "transports": [
            "internal",
            "cable"
        ]
    },
    "clientExtensionResults": {
        "credProps": {
            "rk": false
        }
    }
}

However, I cannot get the credential with the following code:

val getCredentialRequest = GetCredentialRequest(requestChallengeResponse)
val getCredentialResponse = CredentialManager
    .create(context)
    .getCredential(context, getCredentialRequest)

And getCredentialRequest is like:

{
    "publicKey": {
        "rpId": "<rpId>",
        "challenge": "<challenge>",
        "timeout": 60000,
        "userVerification": "required",
        "allowCredentials": [
            {
                "id": "<id>",
                "type": "public-key"
            }
        ]
    }
}

I catch the exception GetCredentialException when calling getCredential(context, getCredentialRequest):

androidx.credentials.exceptions.NoCredentialException: No credentials available
    at androidx.credentials.CredentialProviderFrameworkImpl.convertToJetpackGetException$credentials_release(CredentialProviderFrameworkImpl.kt:276)
    at androidx.credentials.CredentialProviderFrameworkImpl$onGetCredential$outcome$2.onError(CredentialProviderFrameworkImpl.kt:152)
    at androidx.credentials.CredentialProviderFrameworkImpl$onGetCredential$outcome$2.onError(CredentialProviderFrameworkImpl.kt:143)
    at android.credentials.CredentialManager$GetCredentialTransport.lambda$onError$2(CredentialManager.java:694)
    at android.credentials.CredentialManager$GetCredentialTransport.$r8$lambda$nlbYav9mLBoE6Yh1vFKCvITF3ks(Unknown Source:0)
    at android.credentials.CredentialManager$GetCredentialTransport$$ExternalSyntheticLambda2.run(Unknown Source:6)
    at androidx.credentials.CredentialManager$$ExternalSyntheticLambda0.execute(Unknown Source:0)
    at android.credentials.CredentialManager$GetCredentialTransport.onError(CredentialManager.java:693)
    at android.credentials.IGetCredentialCallback$Stub.onTransact(IGetCredentialCallback.java:123)
    at android.os.Binder.execTransactInternal(Binder.java:1344)
    at android.os.Binder.execTransact(Binder.java:1275)

I used the way which is similar to credential manager codelab. And I also checked the request and response of signin of the sample app. My requests and responses are similar. And, the sample app of codelab works perfectly in emulator and physical device. However, I can successfully create credentials and cannot get credentials.

Answer

The obvious answer is that the credential ID in allowCredentials doesn't match the credential ID returned from the create request. Since the IDs are elided above, I can't say if that's true, but note that WebAuthn uses base64url, not standard base64, in case that tripped anything up.

If you've checked that, try setting allowCredentials to an empty list to accept any applicable credential.

If there aren't any applicable credentials, ensure that the RP ID that the credential was created for matches the RP ID used when requesting a credential.

© 2024 Dagalaxy. All rights reserved.