OneSpan Developer: User Local Authentication with an OTP
In this blog post, we will demonstrate how to authenticate an end-user with a One Time Password (OTP). The OTP is generated by the mobile app integrated with the Orchestration SDK and activated on the trusted device of the end-user.
From there, a login request is sent to OneSpan Intelligent Adaptive Authentication (IAA) along with the OTP. This call is made from the web application that is accessed by the end-user.
Before We Begin
Prior to exploring the Login endpoint, you must first be a OneSpan Community member and sign up for a free Intelligent Adaptive Authentication sandbox account. Check out our previous blog, OneSpan Cloud Solutions In Action - MyBank Web Portal Demo, Part I for instructions on how to do so.
You should also be sure to have at least one registered user prior to trying this call. To learn how to register a user, check out OneSpan Developer: Intelligent Adaptive Authentication - User Registration.
Finally, you will need to have the Orchestration sample app activated on the trusted device as we described in the last two blogs: Orchestration SDK (Java Edition) – Trusted Device Activation with Android Studio: Part I and Orchestration SDK (Java Edition) – Trusted Device Activation with Android Studio: Part II
Endpoint URL
The request URL for this API call will resemble the example below: https://{your_tenant_ID}.sdb.tid.onespan.cloud/v1/users/{userID@domain}/login
You won’t need to provide this URL during the tutorial. It is only to show the structure of the URL. The URL will be automatically assigned in the Interactive API when calling the webservice.
Generate an OTP on the Mobile Trusted Device:
In order to login with a virtual OTP, you will need to follow the steps below to obtain one from the sample app. This app was previously activated on the trusted device of the registered user.
- Under Local Authentication click on the “TRY IT” button as highlighted below
- You will be directed to the local authentication page as shown below, where you will be able to request an OTP to login. For the “Protection Type” select “No PIN” to immediately get an OTP without the need to provide any extra authentication method.
- Then you will receive an OTP as shown in the screenshot below to use to login into the following exercise. You must use this OTP within 30 seconds. Otherwise, it will expire, and you will need to generate a new one.
Try It Out
In order to experiment with the Login API, navigate to the IAA Sandbox Interactive API document in your OneSpan Community account. In the Open API Swagger editor, expand the “Users” resource. You will then find an entry for the Login HTTP Post method as shown in the image below:
URL Path Parameters:
For the purpose of the Login API call, there is a required path parameter for the unique user identifier. It will be formatted as userID@domain. An example of the userID is “iaa_user”. It is the userID that has been activated on the trusted device. The portion of the parameter following the “@” sign is the user domain. This entry should be replaced with the “Sandbox User” string shown below, which is present in your Sandbox details section under the “Intelligent Adaptive Authentication” tab of your Sandbox homepage.
User Login Request Body
Under the “Request Body” section of the Login endpoint, select "AdaptiveLoginInput" object type from the dropped down menu as shown below. You will then get an example of the JSON payload of a login request. It will be populated with a sample of the JSON objects which are required by the API of the " AdaptiveLoginInput " object type.
The request body will look like the example below of the Login endpoint’s required fields.
{
"objectType": "AdaptiveLoginInput",
"cddc": {
"browserCDDC": {
"fingerprintRaw": "{browser:{\"userAgent\":Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36},support:{\"ajax\":true,\"boxModel\":undefined,\"changeBubbles\":undefined,\"checkClone\":true,\"checkOn\":true,\"cors\":true,\"cssFloat\":undefined,\"hrefNormalized\":undefined,\"htmlSerialize\":undefined,\"leadingWhitespace\":undefined,\"noCloneChecked\":true,\"noCloneEvent\":undefined,\"opacity\":undefined,\"optDisabled\":undefined,\"style\":undefined,\"submitBubbles\":undefined,\"tbody\":undefined},computer:{\"screenWidth\":2560,\"screenHeight\":1440,\"OS\":\"Microsoft Windows\",\"platform\":\"Win32\"},additional:{}}",
"fingerprintHash": "e96dadc9651f5fe8f071110eb174fe8e7a17a9d7a96b3b1980c13e5b4af3a4d7"
}
},
"relationshipRef": "iaa_user",
"sessionID": "4ED23EA44F23",
"clientIP": "192.168.0.1",
"credentials": {
"authenticator": {
"OTP": "714346"
}
}
}
Request Payload
It contains two mandatory JSON objects shown in the table:
JSON Required Data Fields | Description | Field Data Type |
---|---|---|
objectType* | This is to declare the object type in the request payload is for the purpose of adaptive authentication solution. | Type: Enum Example: “[ AdaptiveLoginInput ]” |
credentials* | This carries the credentials to authenticate the user including the authenticator object. An OTP is one authenticator type, which will be used in this example. | Type: JSON nested object Example: "credentials": { "authenticator": { "OTP": "714346" } |
cddc* | Client Device Data Collector meta data. The two fields browserCDDC and mobileCDDC are mutually exclusive and collectively exhaustive. | Type: string Example: “browserCDDC” or “mobileCDDC” |
relationshipRef* | The Relationship reference of the user ID. | Type: string minLength: 1 maxLength: 150 Example: iaa_user |
staticPassword* | The initial static password assigned to the user. | Type: string minLength: 8 maxLength: 255 example: Test1234 |
sessionID* | Application session identifier formatted as a hexadecimal string; common for all transactions related to the same session. | Type: string pattern: ^[0-9a-fA-F]+$ minLength: 2 maxLength: 100 example: 4ed23ea44f23 |
Calling the Endpoint
At this point, we are ready to make a RESTful call to the Login endpoint using the IAA interactive Sandbox API. To make the call, click on the “Try it out” button shown in the screenshot below and located to the right of the HTTP POST method section. Once requested, you will receive the response body back in a JSON format. It will be similar to the response payload described in the following section.
User Login Response Body
If the OTP was accepted you will receive a response body similar to the example below, with a 200 response code which indicates a successful login.
{
"riskResponseCode": 0,
"sessionStatus": "accepted"
}
Response Body Fields’ Description
The “riskResponseCode” field is the response code from Risk Analytics. The value ‘0’ in the response above indicates that the request was accepted and the user had been authenticated successfully without any extra measures required. Below is a list of other possible values that can be returned by Risk Analytics. Also, additional values can be configured through the Risk Analytics Presentation Service.
Risk Analytics Behaviour |
Risk Response Code (Integer) |
---|---|
Accept | 0 |
Decline | 1 |
Challenge | 2 |
ChallengeSMS | 3 |
ChallengeDevice2FA | 5 |
ChallengeEmail | 8 |
ChallengeCronto | 11 |
ChallengeNoPIN | 21 |
ChallengePIN | 22 |
ChallengeFingerprint | 23 |
ChallengeFace | 24 |
The sessionStatus
field in the JSON response represents the current status of the session after the request has been sent, the table below list the possible status values.
Session Status | Status Description |
---|---|
unknown | The status unknow and the response is being handled externally |
pending | Awaiting an action from the end-user |
accepted | Successfully completed |
refused | Refused by the end-user |
timeout | Timed out after no response was received within the time frame |
failed | The OTP validation fail |
With the steps above completed, the user should have been successfully authenticated. Stay tuned for more blogs on using OneSpan's Intelligent Adaptive Authentication API. Meanwhile, if you have any questions, feel free to reach us on the OneSpan Community Portal Forums.