Laragear / WebAuthn

Authenticate users with Passkeys: fingerprints, patterns and biometric data.
MIT License
295 stars 37 forks source link

[1.2] Configuration options for WebAuthn data properties #55

Closed aaronpk closed 9 months ago

aaronpk commented 11 months ago

Please check these requirements

Description

It would be great if the fields used in the WebAuthn data were configurable instead of being hardcoded to the email and name properties of the user.

https://github.com/Laragear/WebAuthn/blob/1.x/src/WebAuthnAuthentication.php#L28

For example, I might want to use the user's username instead of email as the visible name of the WebAuthn credential.

It should be straightforward to add a configuration option to set these properties.

Code sample

`config/webauthn.php`

...
  'webauthn_data_properties' => [
    'name' => env('WEBAUTHN_NAME_PROP', 'email'),
    'displayName' => env('WEBAUTHN_DISPLAYNAME_PROP', 'name'),
  ]
...
lslqtz commented 9 months ago

I hope that the user can customize the public key generated so that the user can customize the time of its rotation and pass it to the navigator.credentials.get function for use. This is what the browser needs to autofill. (https://github.com/w3c/webauthn/wiki/Explainer:-WebAuthn-Conditional-UI)

A workaround for me:

    optionsResponse = null;
    json = null;
    publicKey = null;
    publicKeyCredential = null;

    async login(request = {}, response = {}, credentials = null) {
        if (this.doesntSupportWebAuthn) {
            alert('Your browser does not support this feature!');
            return;
        }
        if (this.optionsResponse === null) {
            this.prepareLogin({}, {}, false);
        }
        this.credentials = credentials;

        if (this.credentials === null) {
            let publicKey = this.publicKey;
            this.credentials = await navigator.credentials.get({publicKey});
        }

        this.publicKeyCredential = this.mdu_parseOutgoingCredentials(this.credentials);

        Object.assign(this.publicKeyCredential, response);

        console.debug(this.publicKeyCredential);

        return await this.mdu_fetch(this.publicKeyCredential, this.mdu_routes.login, response).then(WebAuthn.mdu_handleResponse);
    }

    async prepareLogin(request = {}, response = {}, wait = true) {
        if (this.doesntSupportWebAuthn) {
            return;
        }
        this.optionsResponse = await this.mdu_fetch(request, this.mdu_routes.loginOptions);
        this.json = await this.optionsResponse.json();
        this.publicKey = this.mdu_parseIncomingServerOptions(this.json);
        if (wait) {
            if (!PublicKeyCredential.isConditionalMediationAvailable || !PublicKeyCredential.isConditionalMediationAvailable()) {
                return;
            }
            let credentials = await navigator.credentials.get({
                mediation: 'conditional',
                publicKey: this.publicKey
            });
            this.login({}, {}, credentials).then(function () {
                location.href = '/';
            }).catch(error => console.error('Login failed.'));
        }
    }
DarkGhostHunter commented 9 months ago

They're hard-coded, but you can easily override the function with your own:


    /**
     * Returns displayable data to be used to create WebAuthn Credentials.
     *
     * @return array{name: string, displayName: string}
     */
    #[ArrayShape(['name' => "string", 'displayName' => "string"])]
    public function webAuthnData(): array
    {
        return [
            'name' => $this->username,
            'displayName' => "$this->username ($this->email)",
        ];
    }
``
DarkGhostHunter commented 9 months ago

I hope that the user can customize the public key generated so that the user can customize the time of its rotation and pass it to the navigator.credentials.get function for use. This is what the browser needs to autofill. (https://github.com/w3c/webauthn/wiki/Explainer:-WebAuthn-Conditional-UI)

I will look into this once I finish a project.

lslqtz commented 9 months ago

Added: I rewrote it (webAuthnData) in user model and it works.

DarkGhostHunter commented 9 months ago

Added: I rewrote it (webAuthnData) in user model and it works.

I shall consider this issue as resolved.