webauthn-framework icon indicating copy to clipboard operation
webauthn-framework copied to clipboard

Android Error

Open Nevercold opened this issue 3 years ago • 12 comments

Hey! I don't know if this is correct and if I'm in the right place. But I just ask.

I get the error when I get the login or register option. On Windows with Windows Hello or iOS with TouchID (iPhone 6s, iOS 15) it works.

Please Help me!

"DOMException: Either the device has received unexpected request parameters, or the device cannot support this request." / NotSupportedError

Smartphone (please complete the following information):

  • Device: Oneplus N10 5G
  • OS (+version): Android 11
  • Browser (+version): Chrome Mobile 103

(And tested on other Android Devices)

I use the latest 4.0 version, in Pure-PHP without framework. Installed via Composer and set up with the documentation.

Response from Option-Request: (censored)

    "rp": {
        "name": "Name",
        "id": "domain.de"
    },
    "pubKeyCredParams": [
        {
            "type": "public-key",
            "alg": -7
        },
        {
            "type": "public-key",
            "alg": -46
        },
        {
            "type": "public-key",
            "alg": -35
        },
        {
            "type": "public-key",
            "alg": -36
        },
        {
            "type": "public-key",
            "alg": -257
        },
        {
            "type": "public-key",
            "alg": -258
        },
        {
            "type": "public-key",
            "alg": -259
        },
        {
            "type": "public-key",
            "alg": -37
        },
        {
            "type": "public-key",
            "alg": -38
        },
        {
            "type": "public-key",
            "alg": -39
        },
        {
            "type": "public-key",
            "alg": -260
        },
        {
            "type": "public-key",
            "alg": -261
        }
    ],
    "challenge": "i1evk27Ry4SnYJdhHD5wiQ",
    "attestation": "none",
    "user": {
        "name": "Niekold",
        "id": "MQ",
        "displayName": "Moritz Walter"
    },
    "authenticatorSelection": {
        "requireResidentKey": true,
        "userVerification": "required",
        "residentKey": "required"
    },
    "excludeCredentials": [
        {
            "type": "public-key",
            "id": "5678"
        },
        {
            "type": "public-key",
            "id": "1234"
        }
    ],
    "timeout": 60000
}```

Nevercold avatar Jul 13 '22 19:07 Nevercold

Hi,

To overcome the issue, you should set the isResidentKeyRequired parameter to false when creating the credential.

It most likely means that you are trying to register a device that is not capable of (or does not allow) the use of resident keys.

Spomky avatar Jul 13 '22 19:07 Spomky

Hi,

To overcome the issue, you should set the isResidentKeyRequired parameter to false when creating the credential.

It most likely means that you are trying to register a device that is not capable of (or does not allow) the use of resident keys.

Thanks for the fast reply! But don't I need this if I want to allow username/password free login?

Nevercold avatar Jul 13 '22 20:07 Nevercold

Have now set it to false via "setRequireResidentKey(false)" . Still same error.

{
    "rp": {
        "name": "",
        "id": ""
    },
    "pubKeyCredParams": [
        {
            "type": "public-key",
            "alg": -7
        },
        {
            "type": "public-key",
            "alg": -46
        },
        {
            "type": "public-key",
            "alg": -35
        },
        {
            "type": "public-key",
            "alg": -36
        },
        {
            "type": "public-key",
            "alg": -257
        },
        {
            "type": "public-key",
            "alg": -258
        },
        {
            "type": "public-key",
            "alg": -259
        },
        {
            "type": "public-key",
            "alg": -37
        },
        {
            "type": "public-key",
            "alg": -38
        },
        {
            "type": "public-key",
            "alg": -39
        },
        {
            "type": "public-key",
            "alg": -260
        },
        {
            "type": "public-key",
            "alg": -261
        }
    ],
    "challenge": "svZFMgQUF1USwM3NfneFOA",
    "attestation": "none",
    "user": {
        "name": "Niekold",
        "id": "MQ",
        "displayName": "Moritz Walter"
    },
    "authenticatorSelection": {
        "requireResidentKey": false,
        "userVerification": "required",
        "residentKey": "required"
    },
    "excludeCredentials": [
        {
            "type": "public-key",
            "id": ""
        },
        {
            "type": "public-key",
            "id": ""
        }
    ],
    "timeout": 60000
}


Nevercold avatar Jul 13 '22 20:07 Nevercold

But don't I need this if I want to allow username/password free login?

Yes, username/password free login is also known as "discoverable WebAuthn/FIDO credential" or more simply "passkeys". It requires a resident key and the user verification.

But for some reasons, it may fails and you should add a way for users to use:

  • passkeys (isResidentKeyRequired=true, residentKey=required and userVerification=required)
  • username/webauthn (isResidentKeyRequired=false, residentKey=preferred and userVerification=preferred)

Spomky avatar Jul 14 '22 03:07 Spomky

I think, Android dont support that yet.

is there a method to check if passkeys are available on the Device?

Nevercold avatar Jul 14 '22 06:07 Nevercold

I think, Android dont support that yet.

Implementations are subject to nuances at the browser app and OS level, but to my knowledge there is no reason for it to fail on Android. Or it may be caused by a root mode enabled on this Android device.

is there a method to check if passkeys are available on the Device?

No, you cannot. That's why the authentication flow should also include the possibilty for the user to set its username. In addition, the device may be temporarily used by another user and it won't be able to login with these options (depends on your use cases).

Spomky avatar Jul 14 '22 06:07 Spomky

No, you cannot. That's why the authentication flow should also include the possibilty for the user to set its username. In addition, the device may be temporarily used by another user and it won't be able to login with these options (depends on your use cases).

So currently I have it like this: There is once the password-free login on the Start of the Loginpage. And there is Fido2 as a 2-factor method after Login (Username+Password). I would just have to adjust the registration process to make this work. I think, thats good.

Implementations are subject to nuances at the browser app and OS level, but to my knowledge there is no reason for it to fail on Android. Or it may be caused by a root mode enabled on this Android device.

I tried it on several devices (Android 10, 11, 12) and it didn't work on any of them. All are not rooted.

Nevercold avatar Jul 14 '22 07:07 Nevercold

Hey,

on normal Login (webauthn) i get the error: "User Handle is mandatory" how i can fix that?

$publicKeyCredentialSource = $this->authenticatorAssertionResponseValidator()->check(
        $publicKeyCredential->getRawId(),
        $authenticatorAssertionResponse,
        $publicKeyCredentialRequestOptions,
        $this->serverRequestCreator()->fromGlobals(),
        userHandle: null
);

Nevercold avatar Jul 15 '22 19:07 Nevercold

When passkey is not available, the userHandle shall be set (last parameter). With this mode, you must:

  • Ask for the username
  • Return options for the selected user (with allowedCredentials list set with the credential descriptions)
  • When receiving the authenticator response, validate it with the user handle you get from the username

Spomky avatar Jul 16 '22 14:07 Spomky

and how i get the userhandle? The only way i found is $userHandle = $authenticatorAssertionResponse->getUserHandle(); but return is empty.

Nevercold avatar Jul 16 '22 18:07 Nevercold

found the way. $key = $this->publicKeyCredentialSourceRepository()->findOneByCredentialId($publicKeyCredential->getRawId());works.

Thanks for the many help!

Nevercold avatar Jul 16 '22 18:07 Nevercold

No, the user handle get be retrieve from the User Entity. It corresponds to the user id. In your case, the user is {"name": "Niekold","id": "MQ","displayName": "Moritz Walter"} and the user handle should be "1".

By the way, user id/handle should be a random string instead of something that can be guessed (e.g. SQL Auto Increment) or private data (e.g. email address).

Spomky avatar Jul 18 '22 20:07 Spomky

Closing as answered

Spomky avatar Aug 23 '22 20:08 Spomky

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

github-actions[bot] avatar Sep 10 '23 00:09 github-actions[bot]