FIDO2 authenticators offer the ability to sign in using multi-factor authentication through the use of authenticator alone. For instance, a PIN or biometric used on the authenticator itself.
To login without usernames and passwords, your security key must implement CTAP2 (e.g. Yubikey 5-series, the FIDO2 Yubikey, or Solokey).
When creating a credential for passwordless authentication, we must specify that the credential will be a resident key and that user verification is required. An example WebAuthn request would be:
/* existing challenge, rp, user, pubKeyCredParams (see installation quickstart) */
// authenticator selection
var authenticatorSelection = {
requireResidentKey: true,
userVerification: "required"
};
navigator.credentials.create({ publicKey: {challenge, rp, user, pubKeyCredParams, authenticatorSelection} })
.then((credentials) => { /* send response to server (see installation quickstart) */ });
With this approach, we do not need to ask the user their username.
When requesting a resident key, the browser may confirm that you are about to use a key that will be stored on the authenticator, since the user ID and RP ID must be persisted and no credential ID will be supplied by the relying party (server). Only one resident key will be stored by the authenticator per RP ID per user ID. Any further registrations will overwrite the existing key.
Subsequent authentication requests will then look like:
// Challenge
let challengeBytesAsString = atob("@Html.Raw(Model.Base64Challenge)");
let challenge = new Uint8Array(challengeBytesAsString.length);
for (let i = 0; i < challengeBytesAsString.length; i++) {
challenge[i] = challengeBytesAsString.charCodeAt(i);
}
// RP ID
let rpId = "@Model.RelyingPartyId";
navigator.credentials.get({ publicKey: {challenge, rpId} })
.then((result) => { /* send response to server (see installation quickstart) */ });