WebAuthn specifies an API for creating and using public key credentials. Credentials belong to a user and are managed by an authenticator. The process of creating credentials is called attestation. Through Attestation the device can be verified as authentic using trust chains. A successful attestation proves that the device the user has authenticated with is authentic and hasn't been tampered with. From a high level end users perspective, you can think of attestation as a kin to registration.
Registration
On user action, such as a button click (browsers may block automatic attestation), the Relying Party can request the client to create a new credential, this is done via interaction with the WebAuthn API by calling the navigator.credentials.create()
method. There are a few different credential options objects we can pass into the function.
- PublicKeyCredential
- PasswordCredential
- FederatedCredential
- IdentityCredential
- OTPCredential
For FIDO however the only credential type required is PublicKeyCredential
.
With the FIDO component the FidoAuthentication
service can be injected into the controller and the InitiateRegistration
called before the page load to supply some of the fields required in the options.
Public Key Credential Options
-
Attestation :
string
Optional
Intended for use by Relying Parties that wish to express their preference for attestation conveyance. Attestation value can either bedirect
,indirect
ornone
. If no value is provided it will default tonone
.direct
attestation means the RelyingParty wants to receive the attestation statement as generated by the authenticator.direct
is the recommended value.indirect
attestation indicates that the RelyingParty prefers a verifiable attestation statement but allows the client to device how to obtain it.none
This means that the relying party is not interested in authenticator attestation.
-
AuthenticatorSelection :
object
Optional
Authenticator requirements object.- AuthenticatorAttachment :
string
platform
indicates a platform authenticator such as WindowsHello or Apple TouchId/FaceId.cross-platform
indicates a roaming authenticator such as a security key.
- RequireResidentKey :
bool
Whentrue
the authenticator must create a discoverable credential (residence key) for username-less authentication. Not all keys support residence keys. - UserVerification :
string
The user verification value can be set aspreferred
,required
ordiscouraged
. If no value is supplied it will default topreferred
.discouraged
means the RelyingParty does not want user verification during the operation, this could be to minimize disruption to the user flow.preferred
means that the RelyingParty prefers user verification if possible but will not fail the if the response does have the AuthenticatorDataFlags.UV set.required
means the operation will fail if the response does have the AuthenticatorDataFlags.UV set. The operation will fail if the key does not support user verification and may fail depending on the browser if no PIN or biometric has been configured
- AuthenticatorAttachment :
-
Challenge :
Uint8Array
A randomly generated value generated by the RelyingParty. In the FIDO2 component the challenge value is generated when callingFidoAuthentication
InitiateRegistration
method. -
ExcludeCredentials :
Array
Limits creation of multiple credentials for the same account on a single authenticator. If the authenticator finds an existing credential type and id for the RP, then a new credential will not be created. TheFidoAuthentication
InitiateRegistration
will supply this a list of all credential ids for the user you can use for this option. -
PubKeyCredParams Specifies which cryptographic algorithms the RelyingParty supports. The FIDO2 component supports the following algorithms
EdDSA
(Ed25519)ES256
ES256K
ES384
ES512
PS256
PS384
PS512
RS1
RS256
RS384
RS512
-
rp :
object
Relying party information.id
The id attribute must equal the domain of the origin seen by the client, or the origin must be a subdomain of the id. If id is omitted, then origins effective domain is used.name
Display name, required.
-
timeout :
int
The time, in milliseconds, that the caller is willing to wait for the call to complete. -
user :
object
Information about the user account.id
The id attribute is the user handle that is generated by the RP and used to uniquely identify a user. Unlike name, id is not meant to be human-readable and should not contain personally identifying information such as an e-mail address
TheFidoAuthentication
InitiateAuthentication
method will generate a user handle to be used here.name
:string
UsernamedisplayName
:string
User-friendly Display name.
Complete Registration
Once WebAuthn has completed its authentication, the authentication data needs to be passed to the FIDO component to perform attestation and validation. The encoded credentials can be turned into JSON and posted to RegisterCallback endpoint via a javascript promise.
navigator.credentials.create({ publicKey }).then((credentials) => {
var encodedCredentials = {
id: credentials.id,
rawId: btoa(String.fromCharCode.apply(null, new Uint8Array(credentials.rawId))),
type: credentials.type,
response: {
attestationObject:
btoa(String.fromCharCode.apply(null, new Uint8Array(credentials.response.attestationObject))),
clientDataJSON:
btoa(String.fromCharCode.apply(null, new Uint8Array(credentials.response.clientDataJSON)))
}
};
$.ajax({
url: '/Home/RegisterCallback',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify(encodedCredentials),
success:function() {
window.location.href = "/";
}
});
});
The FIDO component contains types to model FIDO payloads. To receive the encoded credential object from the browser use Base64FidoRegistrationResponse
. (See code fragment below)
[HttpPost]
public async Task<IActionResult> RegisterCallback([FromBody] Base64FidoRegistrationResponse registrationResponse)
{
IFidoRegistrationResult result = await fido.CompleteRegistration(registrationResponse.ToFidoResponse());
if (result.IsError) return BadRequest(result.ErrorDescription);
return Ok();
}
The FidoAuthentication.CompleteRegistration
method requires a IFidoRegistrationResponse
, the ToFidoResponse
extension method generates a IFidoRegistrationResponse
from the Base64FidoRegistrationResponse
.