Two way OTP authentication

This section covers the API for the Two way OTP authentication module. It's divided into the following subsections:

Introduction

The two way OTP authentication module is an integration module with the portal which acts as an Identity Provider (IdP). The concept used for this authentication module is to have two simple one time passwords (OTP) of 6 digits. There is two way communication involved which makes the two combined codes a strong authentication method. The two way OTP authentication module should be configured as a custom IdP in the Onegini Token Server admin console.

Authentication flow

The basic flow contains three steps. The first step is triggered by the end-user (on his mobile device). This end-user wants to enroll his mobile device (login to the mobile application). In the first step the user is given a code (client code), which must be entered in a web-based portal for end-users. Normally the user would use a laptop to browse to the web-based portal or use his mobile device browser to browse to the portal.

In the second step the user needs to fill in the client code (that was generated in the first step). He needs to enter it on a specific page on the web-based portal. An API call will be made from the portal to the Token Server in order to transfer the client code to the Token Server. This API call must contain the client code and the user id of the user that is logged in into the portal. The result of this API call is a code (the response token). The portal needs to present this code to the end-user.

The last step is that the end-user must enter this response token in the web page served by the Token Server authentication module. When the user has done so the mobile device and user can be linked together by the Token Server. This concludes the two way OTP authentication module.

Generation of the client code

The client code is used to correlate a user action on the enrollment module with the API call made by the portal. The client code is a six digit unique string. A web page (provided by the Token Server) displays this code to the end-user, see the templates section. As the Token Server has no session management a cookie is set in the users' browser to link it to the enrollment transaction. The transaction has a default timeout of five minute. The cookie (and transaction timeout) settings can be set by the Token Server (cookie) properties.

Create Response Token

An API is provided so that the portal can request a response token when the user entered his client code in the portal. The network infrastructure should be set up in such a way that the API can only be reached by the portal which is located in the internal network. Basic authentication is used to provide a basic level of security on the API.

Request token (client code) endpoint: POST /oauth/api/v1/two-way-otp/request-token

Parameter Description
user_id Identifier of the user
client_code The code that was shown to the user by the enrollment module

Example request

POST /oauth/api/v1/two-way-otp/request-token HTTP/1.1
Content-Type: application/json;charset=UTF-8
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
Host: example.invalid
Connection: close
Content-Length: 62

{
  "user_id": "theIdOfTheUser",
  "client_code": "123456"
}

When the two way authentication module was able to find the corresponding transaction a 200 OK HTTP response will be send which contains a JSON body with a response token.

Attribute Description
token The token the user needs to enter on the mobile device to link it on the Token Server

Example response

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
  "token": "12345"
}

When the authentication module fails because the user cannot use one of the scopes that is configured for the client, a JSON response body is returned with a code and a redirect URI. This redirect URI can be an endpoint where the user can read more information why this scope is not available.

Attribute Description
error A short description what went wrong
redirect_uri The URI the user can be sent to in case this error occurs

Example response

{
  "error": "Scope X not available for user",
  "redirect_uri": "https://example.com/scope-x-not-available"
}

When the authentication module was not able to provide a token an HTTP error response is used to provide the error details.

Http error code Description
400 Bad Request One of the required parameters in the request is missing, empty or invalid.
403 Forbidden The provided user_id does not have sufficient rights to access the scopes of the application.
404 Not Found No corresponding enrollment transaction was found. The provided client code is invalid or the transaction is expired.
410 Gone The state of the transaction is invalid, a token was already generated for this transaction.
500 Internal Server Error Something else went wrong

The error message contains a JSON body with a short description of the error.

Example error response body

{
  "error": "No transaction found for specified client code."
}

Entering the Response Token

Once the API call has been made and a response token is generated the token can be entered in the web page delivered by the authentication module of the Token Server. The user need to enter the response token in the appropriate input field on this web page. The Token Server uses the same web page to both display the client code and the input field of the response token.

To check if the user already created a response token (that is, entered the client code in the portal) an AJAX call can be made (from the web page that the Token Server displays) to the Token Server.

This AJAX call can be used to hide the input field for the response token. Sometimes users get confused by the code and the input field and they enter the client code into the input field for the response code.

Endpoint: GET /oauth/two-way-otp/enrollment/generated

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
  "generated": "GENERATED"
}

The generated attribute has one of the following values:

  • GENERATED: the user has entered the client code in the portal. The form can be submitted.
  • NOT_GENERATED: the user has not yet entered the client code in the portal. The form should not be submitted.
  • SESSION_NOT_FOUND: the Token Server cannot find Two Way OTP information for this request.

The user needs to enter the response token on the web page before he can submit the response code. The entered response token will be validated and if the response token is valid the user is authenticated (or linked to the client). The user has a maximum of three attempts to validate the response token. When he fails to do so the process must be started from the first step again: fetch a new client code and enter that in the portal again.

Templates

A set of Thymeleaf templates is available for the two way OTP authentication module. The templates can be customized as long as the below displayed predefined set of variables and messages are used.

Enrollment

File name: two-way-otp-enrollment.html

This template provides the user with a client code and the form to enter the response token that is shown on the portal. The template is responsible to display the client code, the code is given in the client code variable.

<h2 th:text="${clientCode}">_123456</h2>
Element Description
${clientCode} Variable that contains the client code.
${csrfToken} Variable that contains the csrf token.

Another responsibility is to send a POST request with the entered response token.

Example form to post the response token

<form th:action="@{/two-way-otp/enrollment}" method="POST">
  <input type="hidden" th:value="${csrfToken}" name="csrf_token" />
  <input type="text" id="id_token" name="id_token" />
  <input type="submit" value="Continue" />
  <a th:href="@{/two-way-otp/enrollment/cancel}">Cancel</a>
</form>
Element Description
@{/two-way-otp/enrollment} Endpoint to post the token validation request.
@{/two-way-otp/enrollment/cancel} Endpoint to restart the enrollment process and generate a new client code.

The template should have the possibility to display error messages.

Example to display error messages

<div class="alert alert-error" th:if="${message}" id="messageBox">
  <span th:text="#{${message}}">_Message</span>
</div>
Element Description
#{${message}} The message variable contains a message key that represents an error message in the message property file.

The authentication module uses some predefined message keys to communicate errors to the template. These messages should be made available in the messages property file.

Message key Description
twoWayOtp.enroll.error.invalidToken The token provided is invalid.
twoWayOtp.enroll.error.transactionState The state of the transaction was invalid, in order to be able to enter a token the client code should be entered in the portal first.

Failure without recovery

File name: two-way-otp-dead-end.html

When there is no transaction available the Token Server is not able to redirect the user back to the client / app. A page with instructions will be shown to the user on how to continue.

Too many failed attempts

File name: two-way-otp-max-attempts.html

After a number of failed attempts the transaction is invalidated and the user should restart the flow. This template should provide a button to restart the flow.

Example link to restart the flow

<a th:href="@{/two-way-otp/enrollment/cancel}">Restart authentication</a>
Element Description
@{/two-way-otp/enrollment/cancel} Endpoint to restart the enrollment process and generate a new client code.

Events

Event id Description
TWO_WAY_OTP_CREATED Successfully created a token via the portal API.
TWO_​WAY_​OTP_​CREATION_​FAILED_​INVALID_​TRANSACTION_​STATE Failed to create a token via the portal API due to an invalid transaction state.
TWO_​WAY_​OTP_​CREATION_​FAILED_​TRANSACTION_​NOT_​FOUND Failed to create a token via the portal API because the transaction could not be found by the specified client code.
TWO_​WAY_​OTP_​CREATION_​FAILED_​INVALID_​REQUEST Failed to create a token via the portal API due to an invalid request.
TWO_​WAY_​OTP_​CREATION_​FAILED_​FORBIDDEN_​SCOPES Failed to create a token via the portal API because the user is not allowed to use the scopes for the client (e.g. no subscription).
TWO_​WAY_​OTP_​VALIDATED Successfully validated a token.
TWO_​WAY_​OTP_​VALIDATION_​FAILED_​INVALID Failed to validate a token because an invalid token value was provided.
TWO_​WAY_​OTP_​VALIDATION_​FAILED_​INVALID_​MAX_​ATTEMPTS_​REACHED Failed to validate a token because an invalid token value was provided. Due to the fact the maximum number of attempts was reached the transaction was invalidated.
TWO_​WAY_​OTP_​VALIDATION_​FAILED_​INVALID_​TRANSACTION_​STATE Failed to validate a token because the transaction was not in the correct state.
TWO_​WAY_​OTP_​VALIDATION_​FAILED_​TRANSACTION_​NOT_​FOUND Failed to validate a token because the transaction could not be found.
TWO_​WAY_​OTP_​VALIDATION_​FAILED_​INVALID_​CSRF_​TOKEN Failed to validate a token because the cross side request forgery (CSRF) token was incorrect.