During this step, your application will send a challenge to the list of registered devices of the user. The security token will resolve this challenge by adding information and digitally signing the data.
To perform a user authentication using a security device, you need to instantiate a Webauthn\PublicKeyCredentialRequestOptions
object.
Let’s say you want to authenticate the user we used earlier. This options object will need:
A challenge (random binary string)
A timeout (optional)
The Relying Party ID i.e. your application domain (optional)
The list with the allowed credentials
The user verification requirement (optional)
Extensions (optional)
The PublicKeyCredentialRequestOptions
object is designed to be easily serialized into a JSON object. This will ease the integration into an HTML page or through an API endpoint.
For v4.0+, the timeout will be set to null
. The values recommended by the specification are as follow:
If the user verification is discouraged
, timeout should be between 30 and 180 seconds
If the user verification is preferred
or required
, the range is 300 to 600 seconds (5 to 10 minutes)
The user trying to authenticate must have registered at least one device. For this user, you have to get all Webauthn\PublicKeyCredentialDescriptor
associated to his account.
Eligible authenticators are filtered and only capable of satisfying this requirement will interact with the user. Please refer to the User Verification page for all possible values.
Please refer to the Extension page to know how to manage authentication extensions.
The way you receive this response is out of scope of this library. In the previous example, the data is part of the query string, but it can be done through a POST request body or a request header.
What you receive must be a JSON object that looks like as follows:
There are two steps to perform with this object:
Load the data
Verify the loaded data against the assertion options set above
This step is exactly the same as the one described in Public Key Credential Creation process.
Now we have a fully loaded Public Key Credential object, but we need now to make sure that:
The authenticator response is of type AuthenticatorAssertionResponse
This response is valid.
The first is easy to perform:
The second step is the verification against the Public Key Assertion Options we created earlier.
The Authenticator Assertion Response Validator service (variable $authenticatorAssertionResponseValidator
) will check everything for you.
If no exception is thrown, the response is valid and you can continue the authentication of the user.
The Public Key Credential Source returned allows you to know which device was used by the user.
If you want a fine grained Webauthn server
You will need the following components before loading or verifying the data:
An Attestation Statement Support Manager and at least one Attestation Statement Support object
An Attestation Object Loader
A Public Key Credential Loader
An Authenticator Attestation Response Validator
An Extension Output Checker Handler
That’s a lot off classes! But don’t worry, as their configuration is the same for all your application, you just have to set them once. Let’s see all of these in the next sections.
The Public Key Credential Source Repository must implement Webauthn\PublicKeyCredentialSourceRepository
. It will retrieve the credential source and update them when needed.
You can implement the required methods the way you want: Doctrine ORM, file storage… as mentioned on the dedicated page.
The token binding handler is a service that will verify if the token binding set in the device response corresponds to the one set in the request.
Please refer to the dedicated page.
Every Creation Responses contain an Attestation Statement. This attestation contains data regarding the authenticator depending on several factors such as its manufacturer and model, what you asked in the options, the capabilities of the browser or what the user allowed.
With Firefox for example, the user may refuse to send information about the security token for privacy reasons.
Hereafter the types of attestations you can have:
none
: no attestation is provided.
fido-u2f
: for non-FIDO2 compatible devices (old U2F security tokens).
packed
: generally used by authenticators with limited resources (e.g., secure elements). It uses a very compact but still extensible encoding method.
android key
: commonly used by old or disconnected Android devices.
android safety net
: for new Android devices like smartphones.
trusted platform module
: for devices with built-in security chips.
All these attestation types are supported, but you should only use the none
one unless you plan to use the Attestation and Metadata Statement.
The Android SafetyNet Attestation Statement is a JWT that can be verified by the library, but can also be checked online by hitting the Google API. This method drastically increases the security for the attestation type but requires a PSR-18 compatible HTTP Client and an API key.
This object will load the Attestation statements received from the devices. It will need the Attestation Statement Support Manager created above.
This object will load the Public Key using from the Attestation Object.
If you use extensions, you may need to check the value returned by the security devices. This behaviour is handled by an Extension Output Checker Manager.
You can add as many extension checkers as you want. Each extension checker must implement Webauthn\AuthenticationExtensions\ExtensionOutputChecker
and throw a Webauthn\AuthenticationExtensions\ExtensionOutputError
in case of an error.
This object is what you will directly use when receiving Attestation Responses (authenticator registration).
This object is what you will directly use when receiving Assertion Responses (user authentication).
During this step, your application will send a challenge to the device. The device will resolve this challenge by adding information and digitally signing the data.
The application will check the response from the device and get its credential ID. This ID will be used for further authentication requests.
To associate a device to a user, you need to instantiate a Webauthn\PublicKeyCredentialCreationOptions
object.
It will need:
A challenge (random binary string)
A list of supported public key parameters i.e. an algorithm list (at least one)
A timeout (optional)
A list of public key credential to exclude from the registration process (optional)
The Authenticator Selection Criteria (e.g. user presence requirement)
Attestation conveyance preference (optional)
Extensions (optional)
Let’s see an example of the PublicKeyCredentialCreationOptions
object. The following example is a possible Public Key Creation page for a dummy user "@cypher-Angel-3000".
The options object can be converted into JSON and sent to the authenticator using a JS script.
It is important to store the user entity and the options object (e.g. in the session) for the next step; they will be needed to check the response from the device.
What you receive must be a JSON object that looks like as follow:
There are two steps to perform with this object:
Load the data
Verify it with the creation options set above
Now that all components are set, we can load the data we receive using the Public Key Credential Loader service (variable $publicKeyCredential
).
If no exception is thrown, you can go to the next step: the verification.
Now we have a fully loaded Public Key Credential object, but we need now to make sure that:
The authenticator response is of type AuthenticatorAttestationResponse
This response is valid.
The first is easy to perform:
The second step is the verification against
The Public Key Creation Options we created earlier,
The HTTP request
The Authenticator Attestation Response Validator service (variable $authenticatorAttestationResponseValidator
) will check everything for you: challenge, origin, attestation statement and much more.
The library needs PSR-7 requests. In the example below, we use nyholm/psr7-server
to get that request.
If no exception is thrown, the response is valid. You can store the Public Key Credential Source ($publicKeyCredentialSource
) and associate it to the user entity.
The way you store and associate these objects to the user is out of scope of this library. However, please note that these objects implement \JsonSerializable
and have a static method createFromJson(string $json)
. This will allow you to serialize the objects into JSON and easily go back to an object.
If you have just registered a new user, don’t forget to store it in your database as well.