IlConte
IlConte

Reputation: 159

WebAuthn with Windows Hello: PIN prompt missing when allowCredentials specified, only device options shown

I'm working on integrating WebAuthn into my web application and encountering an issue specifically with Windows Hello and the handling of allowCredentials. When I don't specify allowCredentialsin the publicKeyCredentialRequestOptions, I get a prompt allowing me to choose from available credentials, and upon selection, I'm then asked to enter the PIN for the selected credential. This flow works as expected.

However, my goal is to streamline the process by pre-selecting the credential using allowCredentials, thus skipping the credential selection step. When I do specify allowCredentialswith the correct credential ID, the expected PIN prompt does not appear. Instead, I'm only presented with two options: "iPhone, iPad, or Android device" and "Security Key".

Here's the code snippet for context:

const publicKeyCredentialRequestOptions = {
    challenge: serverChallenge,
    rpId: window.location.hostname,
    userVerification: 'required',
    allowCredentials: [
        {
            type: "public-key",
            id: allowCredentials[0].id,
        }
    ],
};

const credential = await navigator.credentials.get({
    publicKey: publicKeyCredentialRequestOptions
});

The allowCredentials[0].id is verified to be correct. The issue is that specifying allowCredentials emphasized textseems to bypass the PIN entry step for Windows Hello, directly prompting for an alternate authentication method instead.

Has anyone faced a similar issue or have insights on why the PIN prompt is bypassed in this case? Any advice on how to ensure the PIN prompt appears when allowCredentials is used would be greatly appreciated.

Thank you for your assistance!

Upvotes: 1

Views: 599

Answers (1)

Asthor
Asthor

Reputation: 1004

I am assuming a bit here but I would guess that the ID you send in is actually not in the format expected. The allowCredential expects a PublicKeyCredentialDescriptor which eexpects that the ID is sent in as a BufferSource. However the PublicKeyCredential response object from the creation is not of the same type. For the PublicKeyCredential the id is a base64url encoded string of the ID and not an actual BufferSource.

This would result in WebAuthn asking all platform authenticators first, and Windows Hello is a Platform Authenticcator, and they would all respond that they don't know said credential which would prompt you to use cross-platform authenticators, or as you refer to it as alternate authenticators.

As I said, I am assuming a bit, but I assume the allowCredentials[0].id is a reference to a PublicKeyCredential in which case swapping to allowCredentials[0].rawId would probably fix the issue.

If it is not a PublicKeyCredential you'd need to convert your id to a BufferSource. As said earlier I assume it is a base64 encoded string so something like new Uint8Array(Buffer.from(allowCredentials[0].id, 'base64')) might solve it. But this all depends a bit that my assumptions are correct.

Upvotes: 0

Related Questions