OutOfBandFidoUafAuthState
The new HTTP client shipped with nevisAuth 4.38.0.12 will likely require changes in this auth state configuration, specifically in the area of certificate configuration and handling.
Visit the migration guide for additional information.
Introduction and overview
The OutOfBandFidoUafAuthState
AuthState manages the UAF authentication in a nevisFIDO server by invoking the Dispatch Token Service. The typical use case is that a client wants to access an application using a desktop, whereas the authentication is done with a mobile device. In this case, a token is dispatched to the mobile device, where the user authenticates.
The UAF authentication process including nevisAuth and the OutOfBandFidoUafAuthState
is as follows:
The
OutOfBandFidoUafAuthState
sends a dispatch target query to retrieve the dispatch targets defined for the user. ThefidoUafUsername
attribute is used to generate this request. The value of this attribute (that is, the username) can be retrieved in different ways:By authenticating the user through an AuthState that is configured before the
OutOfBandFidoUafAuthState
. The username value can be a variable expression usingnotes
.The HTTP client provides the FIDO UAF username directly in the incoming request as JSON or FORM parameters. The username value can be a variable expression using
inargs
.
The nevisFIDO server returns the list of dispatch targets to nevisAuth, which forwards the dispatch targets to the client. If no dispatch targets are found, nevisAuth returns an empty list.
The client selects one of the dispatch targets, if required in interaction with the user. Subsequently, the client sends a request with the dispatch target ID and the username to nevisAuth.
The
OutOfBandFidoUafAuthState
sends a dispatch token request to the nevisFIDO server with the provided dispatch target ID. nevisFIDO uses the Dispatch Token Service for this. In the context of transaction confirmation, theOutOfBandFidoUafAuthState
can be configured with a list of FIDO UAFtransaction
. This list oftransaction
will be sent to the nevisFIDO server as part of theGetUAFRequest
The nevisFIDO server returns a dispatch token response to nevisAuth, which forwards the response to the client. The dispatch token response contains a FIDO UAF session ID. See Example Response Using FCM Dispatcher for a response example.
The client queries nevisAuth. It depends on the configuration of the
fidoUafSessionId
property in theOutOfBandFidoUafAuthState
whether the client must provide this property. By default, the client is required to send thefidoUafSessionId
property in a POST with a payload like this:{ "fidoUafSessionId" : "asdetwdIDsdfsewSAdsds09823423sdfsd9ds" }
The
OutOfBandFidoUafAuthState
processes the authentication status query, by asking the nevisFIDO server whether the user was actually authenticated. If so, theOutOfBandFidoUafAuthState
has a transitionok
. nevisAuth sends a response to the client, including a payload like this:{
"status" : "succeeded",
"timestamp" : "2018-12-14T20:37:48.556Z",
"tokenInformation" : {
"tokenResult" : "tokenRedeemed",
"dispatcherInformation" : {
"name" : "firebase-cloud-messaging",
"response" : "successful dispatch"
}
},
"uafStatusCode" : 1200,
"userId" : "123122233",
"authenticators" : [ {
"aaid" : "ABBA#0001"
} ]
}The client must send another request to nevisAuth to continue with the authentication process.
To allow chained UAF AuthStates, nevisAuth will remove the stored FIDO UAF session ID every time an AuthState transition occurs in the OutOfBandFidoUafAuthState
.
As a consequence, the HTTP client will receive the authenticated
status only once for a given session ID. The next queries with the same session ID will return an unknown
status.
This is to prevent the following undesired situation:
Suppose a given configuration consists of the two chained UAF AuthStates AuthState1 and AuthState2. If the user authenticates in AuthState1, the AuthEngine will make AuthState2 the current AuthState. If the client sends an authentication status request with the session ID used in AuthState1, and the session has not been cleaned up, then the user will be considered authenticated in AuthState2.
Restarting the FIDO UAF Authentication
To be able to retrieve the authentication status, nevisAuth requires the FIDO UAF session ID. If the fidoUafSessionId
property is not provided in the nevisAuth configuration, it must be provided as part of the request (using the fidoUafSessionId
JSON attribute).
In any case where a FIDO UAF session ID cannot be associated with the client, the client will initiate an authentication flow, even though an authentication was already triggered. If you configure fidoUafSessionId
in nevisAuth, the client may lose this ability to control redundant authentications.
The main reasons for requiring the session ID are:
Requiring the session ID adds a security layer to what already is provided by nevisAuth and nevisProxy. Stealing the cookie is not enough to hijack the authentication session. An attacker must also have access to the session ID returned in a previous request by nevisAuth. That is, by stealing the cookie, the attacker can prevent the user from being authenticated by restarting the FIDO UAF authentication (see the point below). However, without the session ID the attacker will not be able to authenticate.
Requiring the session ID allows a client application to restart the FIDO UAF authentication at any point in time. This can help to improve the user experience.
By default, sending a request without a FIDO UAF session ID is enough to restart the FIDO UAF authentication (see step 1 in the previous section). This can be useful in different scenarios, for instance:
- The application requiring authentication is executed in the browser in a laptop whereas the FIDO UAF authentication is done in a mobile device (out-of-band scenario). Suppose the browser polls nevisAuth for the authentication status, but the authentication is still going on after a certain time. Then the application can ask the user to trigger a new FIDO UAF authentication by confirming a message. Note that the browser application could also decide to restart the entire authentication, by removing the nevisAuth cookie. However, this could be annoying for the end user.
- The FIDO UAF client is the one interacting with nevisAuth. The FIDO UAF client detects an error in the interaction with the user. Instead of restarting the entire authentication, the FIDO UAF client can decide to restart only the FIDO UAF authentication.
Security Considerations
The OutOfBandFidoUafAuthState
is able to query dispatch targets for a non-authenticated user. This means that dispatch target information will be exposed to non-authenticated users. This is possible even if you configured the dispatch target query such that it requires SecToken authorization.
If you consider exposing information to non-authenticated users as a concern, not use the OutOfBandFidoUafAuthState
as a first factor authentication. That is, the OutOfBandFidoUafAuthState
should not be the first AuthState in the authentication flow.
Instead, you could use the OutOfBandFidoUafAuthState
as the second factor authentication. In this case, the username is provided by the first factor authentication, typically a username/password-based AuthState.
The OutOfBandFidoUafAuthState
AuthState requires the use of a dispatch target, even though some nevisFIDO dispatchers do not require it. The reason behind is security: when a dispatch target is used, the contents that are dispatched are encrypted, which avoids a number of attacks (for instance QRLJacking attacks using the QR Code Dispatcher).
Channel linking
In out-of-band scenarios the end-user owns two devices. One device (typically a desktop computer or laptop) that tries to access a protected system, or to perform a protected operation, such as a bank transaction. Another device (typically a mobile device) which is in charge of performing the authentication (or part of it) required to access the protected resource. The channel linking refers to a mechanism that allows the end-user to verify that the authentication requested in the mobile device corresponds to the operation triggered by the device trying to access the protected system.
The channel linking can be configured using the channelLinkingMode
AuthState attribute.
Read more about channel linking in the Concept and Integration Guide
Number matching channel linking
Currently, the only channel linking mode supported by the Nevis Mobile Authentication is number matching. With this channel linking mode, when the client requiring authentication is redirected to nevisAuth, and the OutOfBandFidoUafAuthState
is invoked, the AuthState will generate a random string consisting of two digits.
This string is sent to the user’s mobile device (the one performing FIDO UAF authentication) encrypted, and the OutOfBandFidoUafAuthState
will also include the generated random string in the HTTP response that is sent to the user’s laptop.
When the mobile device receives the message (typically with a push notification when using the FCM Dispatcher, it decrypts it and presents the generated random string to the user. The random string is also be presented in the device (laptop) trying to access the protected resource. The user is asked to verify that both strings match before proceeding with authentication.
To enable the number matching channel linking, set visualString
as the value for the channelLinkingMode
configuration attribute.
When using the QR Code Dispatcher, there is no added value to use the number matching linking, because the QR code scan implicitly links the device triggering the operation (laptop) to the authenticating device (the mobile).
The same thing applies to the link dispatcher, which is used when both the device requiring authentication and the device containing the authenticating application are the same.
Channel linking payload
The format of the channel linking information sent to both user devices (typically laptop and mobile device) is described in the table below:
Attribute | Type | Description | Optional |
---|---|---|---|
channelLinking.mode | String | The channel linking verification mode. Currently only visualString is supported. | false |
channelLinking.verificationContent | String | The data used to do the channel linking. | false |
Example:
{
"channelLinking": {
"mode": "visualString",
"content": "42"
}
}
See the encrypted push message for an example on how the channel linking information is transmitted inside the push notification message to the end-users mobile device.
See the response with the dispatch response for an example on how the channel linking information is sent back to the end-users laptop in the HTTP response.
Description
The following table and chapters describe the characteristics of the AuthState.
Topic | Description |
---|---|
Class | ch.nevis.auth.fido.uaf.authstate.OutOfBandFidoUafAuthState |
Logging | FidoUaf |
Auditing | none |
Marker | none |
Methods | process |
Properties
fidoUafUsername
(string, optional)Username of the user in the nevisFIDO server.
Examples:
${inargs:username}
${inargs:o.username.v}
: Provides the username in the request parameter username. For instance if the client sends this payload in the HTTP request{ "username" : "jsmith" }
, the username that will be used isjsmith
.
infoThe
fidoUafUsername
property value might be required several times when contacting the nevisFIDO server (see theInput
andOutput
below for details). If the username is provided by a previous AuthState and not in the HTTP request, do not usenotes
to store and pass thefidoUafUsername
property value. This is because the lifetime ofnotes
is limited to the current request. In this case, use another mechanism, such as the session with thesess
keyword.Optional valueThe property is marked as optional. However, the presence of the value depends on the use case:
- For usernameless authentication the value is optional.
- For the standard out-of-band authentication (non-usernameless), the value is required.
fidoUafServerUrl
(string, required)Base URL of the nevisFIDO server. You cannot use variable expressions to specify this value.
Example:
https://siven.ch:8443/nevisfido
.With this configuration, the FIDO UAF AuthState will send a dispatch target request to
https://siven.ch:8443/nevisfido/token/dispatch/authentication
.dispatchTargetId
(string, optional)The identifier of the dispatch target to which nevisFIDO must send the token.
Default value:
${inargs:o.dispatchTargetId.v}
. With this value, the client must send the dispatch target ID using a POST with the following payload:{ "dispatchTargetId" : "the_dispatch_target_ID" }
dispatcher
(string, optional)The identifier of the dispatcher that must be used by nevisFIDO to send the token. If no dispatcher is provided, then the dispatcher associated with the dispatch target specified with the attribute
dispatchTargetId
will be used. The supported dispatchers are:firebase-cloud-messaging
,png-qr-code
andlink
.Default value:
${inargs:o.dispatcher.v}
. With this value, the client can send the dispatcher using a POST with the following payload:{ "dispatcher" : "png-qr-code" }
If you want to systematically use the dispatcher associated with the dispatch target ID, you can provide an empty String as value:<property name="dispatcher" value=""/>
"firebase-cloud-messaging" dispatcherWhen using
firebase-cloud-messaging
, the dispatcher property must not be "hard-configured" in the auth state configuration, otherwise on a present user and a missingdispatchTargetId
the authentication will halt. The dispatcher must be sent from the client-side together with thedispatchTargetId
, after the user has selected the device the push message must be sent to.dispatchInformation
(string, optional)The dispatch information that will be sent to the nevisFIDO dispatcher. See Dispatch Token Request Format for details.
Default value:
${inargs:o.dispatchInformation.v}
. With this value, the client must send the dispatch information using a POST with the following payload:{ "dispatchInformation" : { "some": "information for the dispatcher" }
channelLinkingMode
(string, optional)The channel linking verification mode. Currently, only two modes are supported:
none
No channel verification information will be generated.
visualString
A random two digit string is generated to perform visual channel linking. See channel linking for details.
Default Value:
none
infoThis is a convenience attribute to generate the channel linking information, send it along the contents of the
dispatchInformation
attribute and return the generated information in the response. The information of thedispatchInformation
attribute will take precedence over the contents of this attribute.fidoUafSessionId
(string, optional)The session ID required to query nevisFIDO for the status of an ongoing authentication.
Default value:
${inargs:o.fidoUafSessionId.v}
.When this parameter is not set, the client must maintain and send the FIDO UAF session ID to nevisAuth using a POST with the following payload:
{ "fidoUafSessionId" : "the_session_ID" }
fidoUafTransactions
(string, optional)The transactions that can be provided to nevisFIDO in the GetUAFRequest. The string represents a JSON array with the transactions as defined in the FIDO UAF Protocol Specification.
Example:
{ "contentType": "text/plain", "content": "VGhlIHRyYW5zYWN0aW9uIGNvbmZpcm1hdGlvbiB0ZXh0" }
fidoUafPolicy
(string, optional)Name of the policy to be used for the authentication. If no value is specified the default policy will be used. See policy configuration for more information regarding configuring multiple policies.
This can be used to restrict the authenticators that can be used by the client to authenticate. For example, if the operation is sensible and biometric authentication is considered to be stronger than PIN, here you can specify a policy that only allows biometric authenticators.
httpclient.*
(string)Configure the outgoing HTTP communication towards nevisFIDO. For a list of valid HTTP properties, see HTTP Client configuration.
Input
Username
If only the username is provided as input, the OutOfBandFidoUafAuthState
will send a dispatch target query to nevisFIDO to retrieve the available dispatch targets for this user.
Username and dispatch target ID
If the dispatch target ID and the username are included in the input (and no FIDO UAF session ID is provided), the OutOfBandFidoUafAuthState
will send a dispatch token request to the nevisFIDO server to trigger an authentication. The dispatch target ID and username can be provided using a POST with the following payload: { "dispatchTargetId" : "the_dispatch_target_ID", "username" : "the_user_name" }
FIDO UAF session ID
If the FIDO UAF session ID is provided as input, the OutOfBandFidoUafAuthState
will query the nevisFIDO server to check whether the session with the provided ID is authenticated. The FIDO UAF session ID can be provided using a POST with the following payload:
{ "fidoUafSessionId" : "the_session_ID" }
This is the equivalent of sending the session ID in the o.fidoUafSessionId.v
attribute of the inargs
.
Transitions
error
If an error occurred in the communication with nevisFIDO.
failed
If nevisFIDO reports a failed authentication (in response to the client’s query for the authentication status).
dispatchFailed
If nevisFIDO reports that the token dispatch failed.
ok
If nevisAuth detects a successfully authenticated user in nevisFIDO. In this case, nevisFIDO responses positively to the client’s query for the authentication status.
Output
Dispatch targets
If the OutOfBandFidoUafAuthState
generated a query dispatch target request, the output is a list of dispatch target objects (coming from the nevisFIDO server in response to the request). The client must identify the correct dispatch target in this list, that is, the target to dispatch the token to.
Dispatch token response
If the OutOfBandFidoUafAuthState
generated a dispatch token request, the output is the dispatch token response coming from the nevisFIDO server. If channel linking has been configured, then the channel linking information will also be included. The client must retrieve the session ID from the dispatch token response. The session ID is needed to poll the authentication status.
Authentication status
If the OutOfBandFidoUafAuthState
queried nevisFIDO for the authentication status of the session, the output is a JSON object describing the status.
Errors
none
Notes
ch.nevis.auth.fido.uaf.authenticators
Contains the JSON serialized FIDO UAF authenticators that were used to successfully complete the FIDO UAF authentication operation at nevisFIDO. Example value:
[{"aaid":"AAAA#2222","keyId":"a2V5SWQy"},{"aaid":"AAAA#1111","keyId":"a2V5SWQx"}]
Example
The AuthState in the following example integrates FIDO UAF authentication in nevisAuth using the nevisFIDO server located in siven.ch
with port 8443
. The FIDO UAF username is retrieved from the username
parameter of the notes
.
<AuthState name="OutOfBandFidoUafAuthState" class="ch.nevis.auth.fido.uaf.authstate.OutOfBandFidoUafAuthState"
resumeState="false">
<ResultCond name="ok" next="AuthDone"/>
<ResultCond name="error" next="AuthError"/>
<ResultCond name="failed" next="AuthError"/>
<property name="fidoUafUsername" value="${sess:username}"/>
<property name="fidoUafServerUrl" value="https://siven.ch:8443/nevisfido"/>
<property name="httpclient.tls.truststoreRef" value="DefaultKeyStore"/>
</AuthState>
The OutOfBandFidoUafAuthState
does not display a GUI. This means that defining GUI elements or setting the property final
to "true" will have no effect.
Request and Response Examples
Request Body Providing Username
It is assumed that the fidoUafUsername
attribute value is ${inargs:o.username.v}
.
{
"username": "jeff"
}
Response Containing Dispatch Targets for User
HTTP/1.1 200 OK
Date: Mon, 25 Jul 2022 11:30:35 GMT
Content-Type: application/json
Transfer-Encoding: chunked
Content-Length: 117
{
"dispatchTargets" : [ {
"id" : "b4ad2a81-5a88-413d-885f-6a1781dbf5a3",
"name" : "My Mobile Phone"
} ]
}
Request Body Providing dispatchTargetId
It is assumed that the fidoUafUsername
attribute value is ${inargs:o.username.v}
and the dispatchTargetId
attribute value is ${inargs:o.dispatchTargetId.v}
.
{
"username": "jeff",
"dispatchTargetId": "054a0272-0822-4dac-9c7b-42a27174d287"
}
Response with the Dispatch Response
{
"dispatchResult" : "dispatched",
"dispatcherInformation" : {
"name" : "firebase-cloud-messaging",
"response" : 0
},
"sessionId" : "0a97d769-136e-4b9a-a187-e2fe09437d64",
"token" : "02ebf804-a25a-4482-a06e-1f141b5946a6",
"channelLinking" : {
"mode" : "visualString",
"content" : "AB"
}
}
Status Request Body
It is assumed that the fidoUafSessionId
attribute value is ${inargs:o.fidoUafSessionId.v}
.
{
"fidoUafSessionId": "1c8a5b00-165c-4a63-ae13-2e03fb7f57ce"
}
Status Response Example
{
"status" : "succeeded",
"timestamp" : "2022-07-25T11:30:47.439Z",
"tokenInformation" : {
"tokenResult" : "tokenRedeemed",
"dispatcherInformation" : {
"name" : "firebase-cloud-messaging",
"response" : "successful dispatch"
}
},
"uafStatusCode" : 1200,
"asmStatusCode" : 0,
"clientErrorCode" : 0,
"userId" : "userId",
"authenticators" : [ {
"aaid" : "ABBA#0001"
} ]
}
Authentication Retry / Fallback Example
During the out-of-band authentication, there are a number of issues that can occur before the user can proceed with the authentication in the mobile device. For instance, if the FCM Dispatcher is being used, some of these potential problems are: the message could not be dispatched because there is a temporary network error between nevisFIDO and the Firebase infrastructure, the message could be displayed but did not reach the authenticating mobile device, the user ignored inadvertently the push message that reached the mobile device, etc.
When one of these situations occur, a new authentication can be triggered as described in Restarting the FIDO UAF Authentication. For example, if the first dispatcher that was used was the FCM dispatcher, the FCM dispatcher can be used again, or it can be chosen to use another dispatcher, like the QR Code Dispatcher as an alternative/fallback; the QR code dispatcher might be considered less user-friendly because it requires more interaction from the user (the user must point the mobile device to do the QR code scan), but it does not have some of the pitfalls of the FCM dispatcher, like the network connectivity issues mentioned above.
In this chapter, the client (typically in a laptop or desktop) that interacts with Nevis (and in particular with nevisAuth), will be referred as HTTP client.
Identifying if an Authentication Restart is Needed
It is the responsibility of the HTTP client communicating with nevisAuth to decide whether another FIDO UAF authentication should be triggered (using the initial dispatcher or a new one). The criteria to be followed (time to wait before triggering the new authentication, whether the new authentication triggering requires the user explicit consent or not, etc.) depends on the desired user interaction. This section just hints which attributes in the responses returned by the OutOfBandFidoUafAuthState
can be used to determine to start a new authentication or not.
There are two main reasons to initiate a new FIDO UAF authentication:
- The dispatch failed. This situation can be identified by the HTTP client by checking the value of the dispatchResult attribute of the dispatch response: if the value is not
dispatched
, then dispatch failed.
To be able to retry out-of-band FIDO UAF authentication after a dispatch failure, the out-of-band-fido-uaf-transitions dispatchFailed
must either not be set to continue to another AuthState
(default behaviour), or the dispatchFailed
transition must be set to continue to another OutOfBandFidoUafAuthState
.
- The dispatch worked (i.e. nevisFIDO could send the message to the Firebase infrastructure), but the user did not receive the push message or did not manage to proceed with the authentication (for instance, because the push message notification was discarded). After a certain time, the HTTP client could decide (after asking directly the end-user or not) to trigger a new FIDO UAF authentication. The situation can be identified by the HTTP client by checking that the value of the status attribute of the status response is
tokenCreated
.
If the message in the initial authentication could be dispatched, the new FIDO UAF authentication must be triggered before the initial authentication fails. By failure it is meant either reaching the authentication time-out in nevisFIDO, or the user providing bad credentials in the device. Once the FIDO UAF authentication fails, the OutOfBandFidoUafAuthstate
will go to the next AuthState configured for the out-of-band-fido-uaf-transitions error
.
Restarting Authentication
To restart the authentication, all the HTTP client must do is to send a new POST request without the session ID on it. In the example below the following OutOfBandFidoUafAuthState
configuration is assumed. In the example the username
is retrieved from the session (set by a previous AuthState, this can be used in a scenario with FIDO UAF as a second factor authentication). The dispatchTargetId
and dispatcher
values allow the HTTP client to provide them using a JSON payload:
<AuthState name="OutOfBandFidoUafAuthState" class="ch.nevis.auth.fido.uaf.authstate.OutOfBandFidoUafAuthState"
final="false">
<ResultCond name="ok" next="AuthDone"/>
<ResultCond name="error" next="AuthError"/>
<ResultCond name="failed" next="AuthError"/>
<property name="fidoUafUsername" value="${sess:username}"/>
<property name="fidoUafServerUrl" value="https://siven.ch:9443/nevisfido"/>
<property name="httpclient.tls.trustStoreRef" value="TrustStoreForNevisFido"/>
<property name="httpclient.tls.keyObjectRef" value="KeyStoreForNevisFido/ClientKeyForNevisFido"/>
<property name="dispatchTargetId" value="${inargs:o.dispatchTargetId.v}"/>
<property name="dispatcher" value="${inargs:o.dispatcher.v}"/>
</AuthState>
The HTTP client can decide to start a new FIDO UAF authentication, but instead of using FCM as dispatcher, it prefers to receive a QR code in PNG format to transfer the required information to the mobile device (i.e. use the QR Code Dispatcher). This can be done by sending a POST HTTP request with the following payload:
{
"dispatcher": "png-qr-code",
"dispatchTargetId": "054a0272-0822-4dac-9c7b-42a27174d287"
}
The response will look like the following:
{
"token" : "98248c42-c9d5-4332-9b28-c3dc497df311",
"sessionId" : "cf34f631-4180-4e85-91dc-a96dcf5aa9b8",
"dispatchResult" : "dispatched",
"dispatcherInformation" : {
"name" : "png-qr-code",
"response" : "<QR Code as PNG encoded using base64 URL>"
}
}
The client can then simply read dispatcherInformation.response
attribute, which contains the QR code in PNG format, and render the QR code, so that the end-user can scan it in the mobile device associated with dispatch target 054a0272-0822-4dac-9c7b-42a27174d287
(only the mobile device containing the dispatch target can decrypt the contents of the QR code).
Once the QR code scanned, FIDO UAF authentication will proceed in the mobile device.