A user is trying to access an HTTP application, for example an e-banking application, which requires authentication. The user must provide the required authentication with a FIDO2 capable authenticator. Furthermore, the HTTP application is protected by Nevis (notably nevisProxy and nevisAuth).
- The user's device and browser must support FIDO2.
- The user already has existing FIDO2 credentials which can be used to authenticate.
- The user opens the web application in the browser.
- The browser tries to access the web application to display information to the user.
- Nevis detects that the browser is not authenticated. It asks the user to provide his login identifier to authenticate.
- The user provides his login information.
- The login information is sent to the Nevis backend.
- After identifying the user, Nevis asks the user to provide FIDO2 authentication.
- The user authenticates using the FIDO2 Authenticator available on the client device.
- The signed FIDO2 assertion is sent to the Nevis backend for validation.
- The user is now authenticated and able to access the web server.
- The user is now logged in and able to access the web application.
The technical flow in the following figure explains the component interaction in detail. The step numbers in the next figure do not correlate with the simplified example above.
The following flow is a simple compact example. Depending on requirements, changes or different approaches might be required. The key fix points are:
- WebAuthn API in the browser.
- FIDO2 HTTP API in nevisFIDO.
- nevisAuth must be aware of the status of the FIDO2 authentication.
The user initiates the FIDO2 authentication.
nevisProxy forwards the userId input to nevisAuth
IdmUserVerifyStateverifies if the provided
userIdmatches any user.
The provided userId from the browser should be mapped to an
extIdso later there is no need to think about what kind of identifier it is. Best approach is to use the
extIdfrom this point forward. You can use the
IdmGetPropertiesStatefor this purpose.
Depending on the flow you would like to implement, at this point you might want to check if the user has a FIDO2 credential or not. The
IdmCredStatusCheckStatedoesn't support FIDO2 credentials, so to do this you will need a
ScriptStateto query nevisIdm via the REST API. see example here
The transition is made to the
ScriptStateimplementing the FIDO2 authentication. In this state it will render the self executing JS.
The JS client submits an empty form POST to get the
ServerPublicKeyCredentialGetOptionsResponse. In this example implementation the
ServerPublicKeyCredentialGetOptionsRequestis generated by the Groovy ScriptSate.
nevisProxy continues the authentication process by calling nevisAuth.
ServerPublicKeyCredentialGetOptionsRequestis created by
ScriptStateand calls the nevisFIDO Options endpoint.
nevisFIDO queries the FIDO2 credentials from nevisIdm.
Challenge is generated and the
A direct response is prepared using the
JS client receives the
JS client initiates an authentication using the received Options response via the WebAuthn API.
Dialog presented to the user by the browser to unlock the private key.
The user authenticates.
The WebAuthn API generates an assertion and returns it to the JS client.
JS client submits assertion to the backend.
ScriptStatein nevisAuth assembles a ServerPublicKeyCredentialForAuthentication JSON payload from the form submit and calls the nevisFIDO REST API.
- nevisFIDO session lookup. (This session is independent of the nevisAuth session)
- nevisFIDO queries the FIDO2 credentials from nevisIdm.
- The FIDO2 credential is updated with a new SignCounter, to prevent replay attacks. (the counter is not increased by a predefined number)
- FIDO2 session is updated to reflect the current status.
- ServerResponse is returned stating the status of the FIDO2 authentication.
ScriptStatedecides next step / does error handling based on implementation.
- nevisAuth returns to nevisProxy with a
- nevisProxy grants access to originally requested resource.