FIDO 2nd factor authentication - REST flow example

Requirements

Component

Requirement

Comments

Airlock IAM

  • Airlock IAM 7.4 or newer.
  • The IAM bundle Enhanced Authentication must be licensed.

For licensing:
Contact order@airlock.com.

Intended solution environment

This example shows how to configure and use the REST authentication flow for authentication with:

  1. Username and password as the first factor.
  2. FIDO as the second factor.

Goal

  • Understand how to configure the Loginapp REST API for FIDO 2nd factor authentication.
  • Understand how to use the Loginapp REST API for FIDO 2nd factor authentication using an example.

All following procedures are exemplary and will vary according to your setup or needs.

Prerequisites

  • An end-user account exists in IAM and has a first factor (e.g. username and password).
  • The end-user has FIDO enabled as a possible authentication method.
  • The end-user has a supported FIDO authenticator.
  • The FIDO authenticator complies with the settings in the FIDO configuration.
  • The end-users browser or mobile app supports FIDO.
  • The FIDO authenticator has been registered with the end-users account.
  • At least one Login REST authentication flow is configured.
  • The FIDO Settings (basic settings) are configured. Especially, the configured relying party ID matches the browser domain when accessing the Loginapp.

Configuration

  1. Go to:
  2. Loginapp >> Authentication Flows >> Default Application >> Authentication Flow

  3. Add the plugin Username Password Authentication Step as the first step.
  4. Add the plugin FIDO Authentication Step as the second step.
  5. Make sure the FIDO Settings are connected within the second step.
  6. Activate the configuration.
  7. The REST authentication API is now ready to use.

For simplicity, the configuration instructions and usage examples are given for the default application within the Loginapp REST API's Authentication API Settings. Therefore, no application selection REST calls are shown.

Step 1 - Check username and password

First, the username and password are checked:

POST /rest/public/authentication/password/check/
{
    "username" : "jdoe",
    "password" : "password1"
}

If the first authentication step succeeds, the second authentication step is initiated. The FIDO Authentication Step tells the REST client to get a FIDO challenge:

HTTP/1.1 200 OK
{
   "meta":{
      "type":"jsonapi.metadata.document",
      "timestamp":"2021-02-09T15:51:17.456+01:00"
   },
   "data":{
      "type":"authentication.session",
      "id":"464250986156095004",
      "attributes":{
       "nextAuthStep":"FIDO_AUTHENTICATION_CHALLENGE_RETRIEVAL_REQUIRED"
      }
   }
}

Step 2 - Get FIDO authentication challenge

To retrieve the challenge, the REST client sends the following requests:

POST /rest/public/authentication/fido/challenge/retrieve

The following example-response replies with a challenge with exactly one allowed credential (i.e. for a specific FIDO Authenticator - the one the end-user registered for this relying party ID earlier):

HTTP/1.1 200 OK
{
   "meta":{
      "type":"jsonapi.metadata.document",
      "timestamp":"2021-02-09T16:00:18.078+01:00"
   },
   "data":{
      "type":"authentication.fido.challenge",
      "id":"476350137",
      "attributes":{
         "publicKeyCredentialRequestOptions":{
            "challenge":"k5o3_DAEYcJgdPt813W_bl8M4qkoOXa2q…",
            "timeout":60000,
            "rpId":"localhost",
            "allowCredentials":[
               {
                  "type":"public-key",
                  "id":"5F1hx2WyqlhQfuC…PSA"
               }
            ],
            "userVerification":"preferred"
         }
      }
   }
}

The CTAP communication between the REST client and the FIDO Authenticator uses the following call to send the response of the challenge back to IAM for verification:

POST /rest/public/authentication/fido/assertion-response/check
{
   "publicKeyCredential":{
      "id":"5F1hx2WyqlhQfuC…PSA",
      "response":{
         "clientDataJSON":"{\"challenge\":\"k5o3_DAEYcJgdPt813W_bl8M4qkoOXa2qHk8yFVMwU0\",\"clientExtensions\":{},\"hashAlgorithm\":\"SHA-256\",\"origin\":\"https://localhost:8443\",\"type\":\"webauthn.get\"}",
         "authenticatorData":"SZYN5YgOjGh0NBcPZHZgW4_krrmihjLHmVzzuoMdl2MBAAAAAg",
         "signature":"MEQCIBS5OKxXsH-VEDB60xwA4I-Fur7Hrj6N8J9auXUKSKclAiAg78H48gw1LUt_Zb9rKHPCjwo0cnJ13o70TSFetEgyGg"
      },
      "type":"public-key"
   }
} 

Successful authentication is confirmed by the usual response:

HTTP 200 OK 
 {
   "meta":{
      "type":"jsonapi.metadata.document",
      "timestamp":"2021-02-09T16:00:20.514+01:00"
   },
   "data":{
      "type":"authentication.session",
      "id":"168878204328802317",
      "attributes":{
         
      }
   }
}