Secure context
This feature is available only in secure contexts (HTTPS), in some or all supporting browsers.
enabling passwordless authentication and/or secure second-factor
authentication without SMS texts.
Web authentication concepts and usage
accounts or sign in to an existing account, and the Web Authentication
API acts as a replacement or supplement to those on those existing
webpages. Similar to the other forms of the Credential Management API, the Web Authentication API has two basic methods that correspond to register and login:
-
- when used with the publicKey option, creates new credentials, either for registering a new account or for associating a new asymmetric key pair credentials with an existing account.navigator.credentials.create()
-
- when used with the publicKey option, uses an existing set of credentials to authenticate to a service, either logging a user in or as a form of second-factor authentication.navigator.credentials.get()
- Server - the Web Authentication API is intended to register new credentials on a server (also referred to as a service or a relying party) and later use those same credentials on that same server to authenticate a user.
- Authenticator - the credentials are created and stored in a device called an authenticator. This is a new concept in authentication: when authenticating using passwords, the password is stored in a user's brain and no other device is needed; when authenticating using web authentication, the password is replaced with a key pair that is stored in an authenticator. The authenticator may be embedded into an operating system, such as Windows Hello, or may be a physical token, such as a USB or Bluetooth Security Key.
A typical registration process has six steps, as illustrated in Figure 1 and described further below. This is a simplification of the data required for the registration process that is only intended to provide an overview.
PublicKeyCredentialCreationOptions
dictionary. PublicKeyCredential
interface (where PublicKeyCredential.response
is the AuthenticatorAttestationResponse
interface). Note most JavaScript programmers that are creating an application will only really care about steps 1 and 5 where the create() function is called and subsequently returns; however, steps 2, 3, and 4 are essential to understanding the processing that takes place in the browser and authenticator and what the resulting data means.authentication registration and the essential data associated with each
action.
The server sends a challenge, user information, and relying party
information to the JavaScript program. The protocol for communicating with the server is not specified and is outside of the scope of the Web Authentication API. Typically, server communications would be REST over https (probably using XMLHttpRequest or Fetch), but they could also be SOAP, RFC 2549 or nearly any other protocol provided that the protocol is secure.
PublicKeyCredential
containing an AuthenticatorAttestationResponse
. AuthenticatorResponse.clientDataJSON
. One of the most important parameters is the origin, which is recorded as part of the clientData so that the origin can be verified by the server later. PublicKeyCredential
, which has a PublicKeyCredential.rawId
that is the globally unique credential id along with a response that is the AuthenticatorAttestationResponse
containing the AuthenticatorResponse.clientDataJSON
and AuthenticatorAttestationResponse.attestationObject
. PublicKeyCredential
is sent back to the server using any desired formatting and protocol (note that the ArrayBuffer properties need to be be base64 encoded or similar).Finally, the server is required to perform a series of checks to ensure
that the registration was complete and not tampered with. These include:
- Verifying that the challenge is the same as the challenge that was sent
- Ensuring that the origin was the origin expected
- Validating that the signature over the clientDataHash and the
attestation using the certificate chain for that specific model of the
authenticator
Authentication
After a user has registered with web authentication, they can subsequently authenticate (a.k.a. - login or sign-in) with the service. The authentication flow looks similar to the registration flow, and the illustration of actions in Figure 2 may be recognizable as being similar to the illustration of registration actions in Figure 1.
PublicKeyCredentialRequestOptions
dictionary, and the resulting data can be found in the PublicKeyCredential
interface (where PublicKeyCredential.response
is the AuthenticatorAssertionResponse
interface) .or nearly any other protocol provided that the protocol is secure. The
parameters received from the server will be passed to the get() call, typically with little or no modification.
AuthenticatorResponse.clientDataJSON
.One of the most important parameters is the origin, which recorded as part of the clientData so that the origin can be verified by the server later.
Promise
to a PublicKeyCredential
with a PublicKeyCredential.response
that contains the AuthenticatorAssertionResponse
. - Using the public key that was stored during the registration request to validate the signature by the authenticator.
- Ensuring that the challenge that was signed by the authenticator matches the challenge that was generated by the server.
- Checking that the Relying Party ID is the one expected for this service.
Interfaces
Navigator.credentials
. The Web Authentication specification adds a publicKey
member to the create()
and get()
methods to either create a new public key pair or get an authentication for a key pair, repsectively.AuthenticatorAttestationResponse
and AuthenticatorAssertionResponse
, which provide a cryptographic root of trust for a key pair. Returned by CredentialsContainer.create()
and CredentialsContainer.get()
, respectively, the child interfaces include information from the browser such as the challenge origin. Either may be returned from PublicKeyCredential.response
.CredentialsContainer.create()
when a PublicKeyCredential
is passed, and provides a cryptographic root of trust for the new key pair that has been generated.CredentialsContainer.get()
when a PublicKeyCredential
is passed, and provides proof to a service that it has a key pair and that the authentication request is valid and approved.Options
CredentialsContainer.create()
.CredentialsContainer.get()
.Examples
For security reasons, web authentication calls (andcreate()
) are cancelled if the browser window loses focus while the call is pending.get()
// sample arguments for registration
var createCredentialDefaultArgs = {
publicKey: {
// Relying Party (a.k.a. - Service):
rp: {
name: "Acme"
},
// User:
user: {
id: new Uint8Array(16),
name: "[email protected]",
displayName: "John P. Smith"
},
pubKeyCredParams: [{
type: "public-key",
alg: -7
}],
attestation: "direct",
timeout: 60000,
challenge: new Uint8Array([ // must be a cryptographically random number sent from a server
0x8C, 0x0A, 0x26, 0xFF, 0x22, 0x91, 0xC1, 0xE9, 0xB9, 0x4E, 0x2E, 0x17, 0x1A, 0x98, 0x6A, 0x73,
0x71, 0x9D, 0x43, 0x48, 0xD5, 0xA7, 0x6A, 0x15, 0x7E, 0x38, 0x94, 0x52, 0x77, 0x97, 0x0F, 0xEF
]).buffer
}
};
// sample arguments for login
var getCredentialDefaultArgs = {
publicKey: {
timeout: 60000,
// allowCredentials: [newCredential] // see below
challenge: new Uint8Array([ // must be a cryptographically random number sent from a server
0x79, 0x50, 0x68, 0x71, 0xDA, 0xEE, 0xEE, 0xB9, 0x94, 0xC3, 0xC2, 0x15, 0x67, 0x65, 0x26, 0x22,
0xE3, 0xF3, 0xAB, 0x3B, 0x78, 0x2E, 0xD5, 0x6F, 0x81, 0x26, 0xE2, 0xA6, 0x01, 0x7D, 0x74, 0x50
]).buffer
},
};
// register / create a new credential
navigator.credentials.create(createCredentialDefaultArgs)
.then((cred) => {
console.log("NEW CREDENTIAL", cred);
// normally the credential IDs available for an account would come from a server
// but we can just copy them from above...
var idList = [{
id: cred.rawId,
transports: ["usb", "nfc", "ble"],
type: "public-key"
}];
getCredentialDefaultArgs.publicKey.allowCredentials = idList;
return navigator.credentials.get(getCredentialDefaultArgs);
})
.then((assertion) => {
console.log("ASSERTION", assertion);
})
.catch((err) => {
console.log("ERROR", err);
});
- Mozilla Demo website and its source code.
- Google Demo website and its source code.
- webauthn.org and its client source code and server source code
Specifications
Browser compatibility
See also
- WordPress Two-Factor Authentication, ( 2FA) is an additional layer of security you can add to your WordPress login page.
Credits
- Source: https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API
- Published under Open CC Attribution ShareAlike 3.0 licence