Closed akanass closed 3 years ago
I think I have my answer :)
If we don't give a username
during assertion phase
, we can't retrieve authenticators so the client will ask the user which one he wants to use but to validate it correctly after, we have to store User Handle
and use it like describe in the documentation.
This validation should be added inside assertion verification phase
because for now only the string
type is checked for this attribute and User Handle
value has to be stored inside AuthenticatorDevice
to be validated.
And to store User Handle
we have to save it during attestation phase
because User Handle
is the user.id
field. This should be a stable, unique identifier for the user - equivalent to a username. However due to privacy considerations it is recommended to set the user handle to a random byte array rather than a username and not using the user primary key store in the db.
If we want to authenticate an user without his username
we have to set residentKey to required
as describe in the specification and the user will be find in the DB with the User Handle
value send by the authenticator.
Else, we have to ask him his username
, retrieve authenticators associated to it, asking for user verification required
and then validating User Handle
to be sure all is good
passwordless.dev is @aseigler's project and my goto for playing around with Passwordless and Usernameless. I took a look at attestation options and distilled the differences down to this:
{
"user": {
"name": "namehere",
"id": "bmFtZWhlcmU",
"displayName": null
},
"authenticatorSelection": {
"requireResidentKey": false,
"userVerification": "preferred"
}
}
{
"user": {
"name": " (Usernameless user created at 2/1/2021 5:53:46 PM)",
"id": "IChVc2VybmFtZWxlc3MgdXNlciBjcmVhdGVkIGF0IDIvMS8yMDIxIDU6NTM6NDYgUE0p",
"displayName": null
},
"authenticatorSelection": {
"requireResidentKey": true,
"userVerification": "preferred"
}
}
(I've omitted common stuff like RP info, challenge, etc...)
So yes, as you called out from the Yubico guide one difference is requireResidentKey: true
(or the new residentKey: "required"
in L2 of the WebAuthn spec).
I started a "Cookbooks" section for the SimpleWebAuthn docs to document this exact thing: a collection of options devs can specify to support either of these flows. I'll experiment with this in the next few days and restart that effort to document these collections of settings.
@MasterKale thanks for your answer.
For both, we have to store User Handle
like this we can validate the user when is authenticated with username or not by finding the user in the database with the User Handle
value.
And user verification should be required for both to ensure the security.
That's why I'm asking you to add this field inside AuthenticatorDevice
and validate it during verification
phase.
Okay, after a few hours diving back into the spec I understand better now that for the sake of privacy userHandle
(as user.id
in attestation options) should always be a random 64-byte Buffer and never the user's actual internal DB ID.
This means that generateAttestationOptions()
should be updated to generate that random userHandle
every time and return it in attestation options. It'd then be the responsibility of the RP to take that userHandle, persist it until verification, then store it in the credentials
table along with an fkey to the user's actual internal DB ID.
There's now additional load, outside of library functionality, to communicate all of this to people implementing this library who wish to take advantage of passwordless or usernameless flows...
That's why I'm asking you to add this field inside AuthenticatorDevice and validate it during verification phase.
I understand your request better now, too, and this makes perfect sense (with the clarification that "during verification phase" means during assertion verification). I'm going to model upcoming changes around this diagram on this specific page in Yubico's dev guide:
Thanks @MasterKale and yes if we match the specific credentials data from Yubico I guess we are on the good way
UserHandle will allow us to find user in the database and the corresponding authenticator like this we can be sure that it was registered for this RP that's why we have to find AuthenticatorDevice inside the DB with UserHandle and validate all the fields save during attestation generation with the data received during attestation verification.
This issue is going to end up becoming a documentation issue, since PR #97 is adding additional return values from attestation that will be helpful in supporting passwordless and usernameless flows. Once that PR gets merged in work can begin on adding entries to the SimpleWebAuthn docs site containing "best practices" for setting up the RP to support these non-2FA WebAuthn flows.
I'm going to close this issue out for https://github.com/MasterKale/SimpleWebAuthn-homepage/issues/2.
As described in the Yubico developer Guide we can use
User Handle
to allow usernameless and passwordless authentication.How to do it with this library and initiate
attestation
andassertion
phases without ausername
because all documentation describes an associated user passed in parameter.Thanks for your help.