Overview
miniOrange Multi-Factor Authentication Service provides various types of authentication methods which can be easily configured and used for authentications.
Types of authentication methods provided are:
Methods | Description |
---|---|
OTP over SMS | A 6-8 digit OTP is sent on user’s mobile which he then enters to validate himself. |
OTP over EMAIL | A 6-8 digit OTP is sent on user’s email which he then enters to validate himself. |
Out-of-Band SMS | An SMS is sent on user’s mobile containing links to Accept or Deny the transaction. |
Out-of-Band EMAIL | An email is sent on user containing links to Accept or Deny the transaction. |
Phone Verification | User receive a voice call telling a 4-8 digit numeric key which he needs to enter to authenticate himself. |
KBA (Security Questions) | User is asked to answer some questions which he had configured. |
Soft Token * | User is asked to enter the 6 digit code generated on his mobile by our miniOrange Authenticator mobile app. |
Hardware Token ** | User needs to plug in his hardware token to validate himself. |
Push Notification * | User receives a push notification on his mobile to Accept or Deny the transaction. |
Mobile Authentication * | User needs to scan a QR code from our i’m me mobile app to validate himself. |
Voice Authentication * | User needs to validate himself through his voice. |
Google Authenticator *** | User is asked to enter the 6 digit code generated on his mobile by Google Authenticator app. |
* These authentication methods require miniOrange i’m me mobile app available for Android and Apple smartphones.
** This method require hardware token provided by miniOrange.
*** This method require Google Authenticator app.
NOTE: Some methods need some prior configuration by the end users before they can be used for authentication.
This guide will help you integrate your application with miniOrange Multi-Factor Authentication Service using our Rest APIs.
Pre-requisites
- You need to create a free trial account with miniOrange.
- Login to miniOrange console and Click on the Settings provided on the right top corner of the console and Copy your Api Key and add it in request headers.
Integrating with miniOrange Multi-Factor Authentication Service
There are 2 scenarios for calling Rest APIs:
- Your end users are enrolled with us: We have the information about your users and their configurations.
- Your end users are NOT enrolled with us: We don’t have any information about your users, but you will provide the information while calling our rest APIs
We will cover these 2 scenarios one by one in detail.
The authentication methods supported by these 2 scenarios are:
End users Enrolled with us | End users NOT Enrolled with us |
---|---|
OTP over SMS | OTP over SMS |
OTP over EMAIL | OTP over EMAIL |
Out-of-Band SMS | Out-of-Band SMS |
Out-of-Band EMAIL | Out-of-Band EMAIL |
Phone Verification | Phone Verification |
KBA (Security Questions)* | |
Soft Token * | |
Hardware Token * | |
Push Notification * | |
Mobile Authentication * | |
Voice Authentication * | |
Google Authenticator * |
* Prior configuration by end user is necessary for these types of authentications.
-
Your end users are enrolled with us
If your End Users are enrolled with us, along with OTP over SMS, OTP over EMAIL, Out-of-Band SMS, Out-of-Band EMAIL & Phone Verification, you can also use Soft Token, Hardware Token, Push Notifications, Mobile Authentication, Voice Authentication and Google Authenticator as the authentication methods. These additional methods of authentication require prior configurations before they can be used.
NOTE:
- In case of Soft Token, Hardware Token or Google Authenticator, only validation request needs to be sent.
- In case of Out-of-Band SMS, Out-of-Band EMAIL, Push Notifications or Voice Authentication, authentication staus polling
API needs to be called after challenge request API to check if the transaction has been accepted or denied by the user.
Before calling challenge or validate API, you need to set the following values as authorization header.
The sample java and php code for creating authorization header
- Java
- PHP
/* The customer Key provided to you */
String customerKey = "<YOUR_CUSTOMER_KEY>";
/* The customer API Key provided to you */
String apiKey = "<YOUR_API_KEY>";
/* Current time in milliseconds since
midnight, January 1, 1970 UTC. */
String currentTimeInMillis = String.valueOf(System.currentTimeMillis());
/* Creating the Hash using
SHA-512 algorithm (Apache Shiro library) */
String stringToHash = customerKey + currentTimeInMillis + apiKey;
String hashValue = new Sha512Hash(stringToHash).toHex().toLowerCase();
HttpPost postRequest = new HttpPost("<URL for calling API>");
/* Setting the Authorization Header values */
postRequest.setHeader("Customer-Key", customerKey);
postRequest.setHeader("Timestamp", currentTimeInMillis);
postRequest.setHeader("Authorization", hashValue)
/* The customer Key provided to you */
$customerKey = "<YOUR_CUSTOMER_KEY>";
/* The customer API Key provided to you */
$apiKey = "<YOUR_API_KEY>";
/* Current time in milliseconds since midnight, January 1, 1970 UTC. */
$currentTimeInMillis = round(microtime(true) * 1000);
/* Creating the Hash using SHA-512 algorithm */
$stringToHash = $customerKey . number_format ( $currentTimeInMillis, 0, '', '' ) . $apiKey;
$hashValue = hash("sha512", $stringToHash);
$customerKeyHeader = "Customer-Key: " . $customerKey;
$timestampHeader = "Timestamp: " . number_format ( $currentTimeInMillis, 0, '', '' );
$authorizationHeader = "Authorization: " . $hashValue;
/* Add $customerKeyHeader,$timestampHeader and $authorizationHeader
in the httpheader */
Calling our Challenge API
To challenge, you need to make a HTTP POST request to our Challenge API. Our Challenge Rest API accepts the JSON input in the following format:
Rest Service URL: https://login.xecurify.com/moas/api/auth/challenge
Attribute | Description |
---|---|
customerKey * | Your customer key. |
username * | This is the email that you provided while enrolling the user with us. |
authType | The type of method you want this user to authenticate with. If this field is not provided, the authentication method set by the user will be used for authentication. Valid values: SMS, EMAIL, OUT OF BAND SMS, OUT OF BAND EMAIL, PHONE VERIFICATION, PUSH NOTIFICATIONS, MOBILE AUTHENTICATION, VOICE AUTHENTICATION |
transactionName | Any transaction details that you would like to send to user to give information about the transaction. (Max limit 30 characters) |
* These fields are mandatory.
The following is the JSON Response generated by the Generate Rest API.
{
/* JSON Response Object for Challenge Request */
{
"txId": "ba65583b-7c80-11e5-883e-0e2fb063e0f9",
"authType": "SMS",
"responseType": "CHALLENGE",
"phoneDelivery": {
"contact": "1234567890",
"sendStatus": "SUCCESS",
"sendTime": "1445932803070"
}
"emailDelivery": { /* in case email is sent to user */
"contact": "xyz@example.com",
"sendStatus": "SUCCESS",
"sendTime": "1445932803070"
}
status: "SUCCESS",
message: "Successfully generated.",
"qrCode":"qr-code-value" /* Can be used to display QR code in case user has opted
for mobile authentication*/
questions: [ /* Can be used to display questions in case user has opted for KAB */
{
"question": "your configured question 1?",
},
{
"question": "your configured question 2?",
}
]
}
}
Attribute | Description |
---|---|
txId | This is the transaction ID for your generation request. |
authType | This is the second factor authentication Type for which you send request. |
responseType | This shows the type of response i.e. Response for Generate request or Validate request. Valid values: CHALLENGE, VALIDATEright-aligned |
emailDelivery | The email delivery status. It is provided in case authentication is done through email. |
phoneDelivery | The phone delivery status. It is provided in case authentication is done through mobile. |
contact | The contact OTP sent on i.e phone number or email-id. |
sendStatus | The status of sending the above contact. Valid values: SUCCESS, ERROR |
sendTime | Timestamp showing time of sending. |
message | An additional message showing overall status of the request. |
status | Overall status of the generation/validation request. Valid values: SUCCESS, ERROR |
qrCode | In case user has opted for mobile authentication, this value contains base64 encoded string that can be used to show QR Code image (JPG format) for scanning. |
questions | In case user has opted for KBA, the list of questions can be used to show the user for answering them . |
Calling our Validate OTP rest API
To validate an OTP, you need to make an HTTP POST request to our Validate Rest API. Our Validate Rest API accepts the JSON input in the following format:
Rest Service URL: https://login.xecurify.com/moas/api/auth/validate
-
If authentication Type is Soft Token, Hardware Token or Google Authenticator. There is no need to call Challenge API. These authentication methods require prior configuration before they can be used.
{ /* JSON Object for Validation Request*/ { "customerKey":"abc", /* Your customer key */ "username": "xyz@example.com" /* The User email that you provided to us during enrolment */ "token":"123456", /* The one time passcode generated by app or usb token */ "authType":"SOFT TOKEN" } }
Attribute Description customerKey* Your customer key. username * This is the email that you provided while enrolling the user with us. token * The OTP token user entered for validation. authType The typr of method for whcih OTP needs to be validated. Here authType can be SOFT TOKEN, HARDWARE TOKEN or GOOGLE AUTHENTICATOR.If this field is not provided, the authentication method set by the user will be used for authentication. * These fields are mandatory.
-
If authentication Type is KBA. This authentication method require prior configuration before it can be used.
{ /* JSON Object for Validation Request */ { "txId":"ba65583b-7c80-11e5-883e-0e2fb063e0f9", "answers":[ { "question":"your configured question 1", "answer":"user's answer" }, { "question":"your configured question 2", "answer":"user's answer" } ] } }
Attribute Description txId The transaction ID for which request was generated. answers The list of questions and answers to verify. -
If authentication type is SMS,EMAIL or PHONE VERIFICATION
{ /* JSON Object for Validation Request */ { "txId":"ba65583b-7c80-11e5-883e-0e2fb063e0f9", "token":"123456" } }
Attribute Description txId The transaction ID for which request was generated. token The OTP token user entered to verify. The following is the JSON Response generated by the above Validate Rest API.
{ /* JSON Response Object for Validation Request */ { "txId": "ba65583b-7c80-11e5-883e-0e2fb063e0f9" "responseType": "VALIDATE" "status": "SUCCESS" "message": "Successfully Validated." } }
Attribute Description txId This is the transaction ID for your generation request. responseType The OTP token user entered to verify. status Overall status of the generation/validation request. Valid values: SUCCESS, ERROR, FAILED message An additional message showing overall status of the request. -
If authentication method is OUT OF BAND SMS, OUT OF BAND EMAIL, MOBILE AUTHENTICATION, PUSH NOTIFICATIONS & VOICE AUTHENTICATION. These methods require prior configuration before they can be used. Authentication Status polling API needs to be called to check if transaction has been accepted or denied by the user. In case of Mobile Authentication, polling API is called to check whether valid user has scanned the QR-Code.
To poll, you need to make an ajax HTTP POST request to our Authentication Status API.
{ var timeout; pollValidation(); function pollValidation() { var transId = "<transaction Id generated by challenge API>"; var jsonString = "{\"txId\":\""+ transId + "\"}"; var postUrl = "<authentication status API url>"; jQuery.ajax({ url: postUrl, type : "POST", dataType : "json", data : jsonString, contentType : "application/json; charset=utf-8", success : function(result) { var status = JSON.parse(JSON.stringify(result)).status; if (status == 'SUCCESS') { /* authentication is successfull. */ } else if (status == 'ERROR' || status == 'FAILED' || status == 'DENIED') { /* authentication is failed or denied. */ } else { timeout = setTimeout(pollValidation, 3000); /* start polling. */ } } }); } }
Attribute Description txId This is the transaction ID for your challenge request. status Overall status of the generation/validation request. Valid values: SUCCESS, ERROR, FAILED
More Examples
Example 1
Challenge Request
{
{
"customerKey":"abc",
"username": "xyz@example.com"
}
}
In this case the authentication type set by user will used for authentication. Let say user has set OTP over SMS as his authentication method.
Challenge Response
The response for this would be:
{
{
"txId": "ba65583b-7c80-11e5-883e-0e2fb063e0f9",
"authType": "SMS",
"responseType": "CHALLENGE",
"phoneDelivery": {
"contact": "1234567890",
"sendStatus": "SUCCESS",
"sendTime": "1445932803070"
},
"status": "SUCCESS",
"message": "Successfully generated."
}
}
Validation Request
{
{
"txId":"ba65583b-7c80-11e5-883e-0e2fb063e0f9",
"token":"123456"
}
}
In this case the authentication type set by user will used for authentication. Let say user has set OTP over SMS as his authentication method.
Validation Response
The response for this would be:
{
{
"txId": "fc727646-7c91-11e5-883e-0e2fb063e0f9",
"responseType": "VALIDATE",
"status": "SUCCESS",
"message": "Successfully Validated"
}
}
Example 2
Challenge Request
Let say you want to override the method saved by the user and use PUSH NOTIFICATION instead:
{
{
"customerKey":"abc",
"username": "xyz@example.com"
"authType":"PUSH NOTIFICATIONS"
"transactionName":"Buy Casio Watch $200"
}
}
This will work only if user has configured push notification on his mobile.
Challenge Response
User will receive push notification on his mobile with transaction details that you provided:
{
{
"txId": "fc727646-7c91-11e5-883e-0e2fb063e0f9",
"authType": "PUSH NOTIFICATIONS",
"responseType": "CHALLENGE",
"status": "SUCCESS",
"message": "Successfully generated."
}
}
To check if user has accepted the push notification, you need to call authentication status polling API.
Validation Request
Let say you want to override the method saved by the user and use SOFT TOKEN instead:
{
{
"customerKey": "abc",
"username": "xyz@example.com",
"token": "123456",
"authType": "SOFT TOKEN"
}
}
This will work only if user has configured Soft Token on this mobile.
Validation Response
The response for this would be:
{
{
"txId": "fc727646-7c91-11e5-883e-0e2fb063e0f9",
"responseType": "VALIDATE",
"status": "SUCCESS",
"message": "Successfully Validated"
}
}
d. our end users are NOT enrolled with us
If your End Users are not enrolled with us, you can still use our authentication service. In this case, you will need to provide us the phone number or email where you want us to send the OTP. The authentication methods which can be used here are SMS, EMAIL, OUT OF BAND SMS, OUT OF BAND EMAIL, PHONE VERIFICATION.
i. Calling our Challenge OTP Rest API
You need to make a HTTP POST request to our Challenge Rest API. Our Challenge Rest API accepts the JSON input in the following format:
Rest Service URL: (https://login.xecurify.com/moas/api/auth/challenge)
{
/* JSON Object format for generation request */
{
"customerKey":"abc", /* Your customer key */
"email":"xyz@example.com" /* The email to send OTP to */
"phone":"1234567890" /* phone number to send OTP to */
"authType":"SMS AND EMAIL"
"transactionName":"transaction-details",
}
}
Attribute | Description |
---|---|
customerKey * | Your customer key. |
phone | The phone number where you would like us to send OTP to. |
The email ID where you would like us to send OTP to. | |
authType * | The authentication method you would like to use. Valid values: SMS, EMAIL, SMS AND EMAIL, OUT OF BAND SMS, OUT OF BAND EMAIL |
transactionName | Any transaction details that you would like to send to user to give information about the transaction. (Max limit 30 characters) |
* These fields are mandatory.
NOTE: Either phone or email is required for us to send OTP. If both are provided then OTP will be sent on both the contacts.
The following is the JSON Response generated by the Generate Rest API.
{
/* JSON Response Object for Generation Request */
{
"txId: "fc727646-7c91-11e5-883e-0e2fb063e0f9",
"authType": "SMS AND EMAIL",
"responseType: "CHALLENGE",
"phoneDelivery": {
"contact": "1234567890",
"sendStatus": "SUCCESS",
"sendTime": "1445932803070"
}
"emailDelivery": {
"contact": "xyz@example.com",
"sendStatus": "SUCCESS",
"sendTime": "1445932803070"
}
"status": "SUCCESS",
"message": "Successfully generated."
}
}
Attribute | Description |
---|---|
txId | This is the transaction ID for your generation request. |
authType | The authentication methods SMS, EMAIl, SMS AND EMAIL, OUT OF BAND SMS, OUT OF BAND EMAIL. |
responseType | This shows the type of response i.e. Response for Challenge request or Validate request.Valid values: CHALLENGE, VALIDATE |
emailDelivery | The email delivery status. It is provided in case authentication is done through email. |
phoneDelivery | The phone delivery status. It is provided in case authentication is done through to mobile. |
contact | The contact OTP sent on i.e. mobile or email. |
sendStatus | The status of sending the above contact.Valid values: SUCCESS, FAILED, ERROR |
sendTime | Timestamp showing time of sending. |
message | An additional message showing overall status of the request. |
status | Overall status of the challenge/validation request. Valid values: SUCCESS, FAILED, ERROR |
ii. Calling our Validate OTP Rest API
To validate an OTP, in case authentication method is SMS, EMAIL or PHONE VERIFICATION, you need to make an HTTP POST request to our Validate Rest API. Our Validate Rest API accepts the JSON input in the following format:
Rest Service URL: https://login.xecurify.com/moas/api/auth/validate
{
/* JSON Object for Validation Request */
{
"txID": "fc727646-7c91-11e5-883e-0e2fb063e0f9",
"token": "123456"
}
}
Attribute | Description |
---|---|
txId | The transaction ID for which request was generated. |
token | The OTP token user entered to verify. |
The following is the JSON Response generated by the Validate Rest API.
{
/* JSON Response Object for Validation Request */
{
txId: "fc727646-7c91-11e5-883e-0e2fb063e0f9"
responseType: "VALIDATE"
status: "SUCCESS"
message: "Successfully Validated"
}
}
Attribute | Description |
---|---|
txId | The transaction ID for which request was generated. |
responseType | The OTP token user entered to verify. |
status | Overall status of the generation/validation request.Valid values: SUCCESS, ERROR, FAILED |
message | An additional message showing overall status of the request. |
-
If authentication method is OUT OF BAND SMS or OUT OF BAND EMAIL then Authentication Status polling API needs to be called to check if transaction has been accepted or denied by the user.
To poll, you need to make an ajax HTTP POST request to our Authentication Status API.
{
var timeout;
pollValidation();
function pollValidation()
{
var transId = "<transaction Id generated by challenge API>";
var jsonString = "{\"txId\":\""+ transId + "\"}";
var postUrl = "<authentication status API url>";
jQuery.ajax({
url: postUrl,
type : "POST",
dataType : "json",
data : jsonString,
contentType : "application/json; charset=utf-8",
success : function(result) {
var status = JSON.parse(JSON.stringify(result)).status;
if (status == 'SUCCESS') {
/* authentication is successfull. */
} else if (status == 'ERROR' || status == 'FAILED' || status == 'DENIED') {
/* authentication is failed or denied. */
} else {
timeout = setTimeout(pollValidation, 3000); /* start polling. */
}
}
});
}
}
Attribute | Description |
---|---|
txId | The transaction ID for which request was generated. |
status | Overall status of the authentication status request. Valid values: SUCCESS, ERROR, FAILED, DENIED |
c. Some more Examples
Challenge Request
{
{
"customerKey":"abc",
"phone":"1234567890",
"authType":"SMS"
}
}
Challenge Response
The response for this would be:
{
{
"txId": "fc727646-7c91-11e5-883e-0e2fb063e0f9",
"authType": "SMS",
"responseType": "CHALLENGE",
"phoneDelivery": {
"contact": "1234567890",
"sendStatus": "SUCCESS",
"sendTime": "1445932803070"
}
"status": "SUCCESS",
"message": "Successfully generated."
}
}
Challenge Request
{
{
"customerKey":"abc",
"phone":"1234567890"
"authType":"OUT OF BAND SMS"
}
}
Challenge Response
User will receive an SMS with Accept and Deny link on this phone number. The response of this would be:
{
{
"txId": "fc727646-7c91-11e5-883e-0e2fb063e0f9",
"authType": "SMS",
"responseType": "CHALLENGE",
"phoneDelivery": {
"contact": "1234567890",
"sendStatus": "SUCCESS",
"sendTime": "1445932803070"
}
"status": "SUCCESS",
"message": "Successfully generated."
}
}
Validation Request
{
{
"txId": "fc727646-7c91-11e5-883e-0e2fb063e0f9",
"otpToken":"123456"
}
}
Suppose only phone was provided during the challenge request.
Validation Response
The response for this would be:
{
{
"txId": "fc727646-7c91-11e5-883e-0e2fb063e0f9"
"responseType": "VALIDATE"
"status": "SUCCESS"
"message": "Successfully Validated"
}
}
e. The response for this would be:
- Java
- PHP
public String callChallengeRestApi() {
/* The challenge rest api url which needs to be called to challenge the user. */
String generateUrl = "URL-provided-by-us";
/* The customer Key provided to you */
String customerKey = "<YOUR_CUSTOMER_KEY>";
/* The customer API Key provided to you */
String apiKey = "<YOUR_API_KEY>";
/* Current time in milliseconds since midnight, January 1, 1970 UTC. */
String currentTimeInMillis = String.valueOf(System.currentTimeMillis());
/* Creating the Hash using SHA-512 algorithm (Apache Shiro library) */
String stringToHash = customerKey + currentTimeInMillis + apiKey;
String hashValue = new Sha512Hash(stringToHash).toHex().toLowerCase();
/* The JSON string containing the request information */
String jsonRequestString = "{\"customerKey\":\"" + customerKey + "\",\"username\":\"xyz@example.com\"}";
/* Initializing default Http Client */
HttpClient httpClient = new DefaultHttpClient();
HttpPost postRequest = new HttpPost(generateUrl);
/* Setting jsonRequestString as StringEntity */
StringEntity input = new StringEntity(jsonRequestString);
input.setContentType("application/json");
postRequest.setEntity(input);
/* Setting the Authorization Header values */
postRequest.setHeader("Customer-Key", customerKey);
postRequest.setHeader("Timestamp", currentTimeInMillis);
postRequest.setHeader("Authorization", hashValue);
/* Calling the rest API */
HttpResponse httpResponse = httpClient.execute(postRequest);
/* If invalid response is received, throwing a Runtime Exception */
if (httpResponse.getStatusLine().getStatusCode() != 200) {
throw new RuntimeException("Invalid response received from authentication server. HTTP error code: "
+ response.getStatusLine().getStatusCode());
}
/* If a valid response is received, get the JSON response string */
BufferedReader br = new BufferedReader(new InputStreamReader((httpResponse.getEntity().getContent())));
String output, jsonResponseString = "";
while ((output = br.readLine()) != null) {
jsonResponseString += output;
}
httpClient.getConnectionManager().shutdown();
return jsonResponseString;
}
<?php
function callGenerateRestApi() {
/* The challenge rest api url which needs to be called to challenge the user. */
$generateUrl = "URL-provided-by-us";
/* The customer Key provided to you */
$customerKey = "<YOUR_CUSTOMER_KEY>";
/* The customer API Key provided to you */
$apiKey = "<YOUR_API_KEY>";
/* Current time in milliseconds since midnight, January 1, 1970 UTC. */
$currentTimeInMillis = round(microtime(true) * 1000);
/* Creating the Hash using SHA-512 algorithm */
$stringToHash = $customerKey . number_format ( $currentTimeInMillis, 0, '', '' ) . $apiKey;
$hashValue = hash("sha512", $stringToHash);
/* The Array containing the request information */
$jsonRequest = array("customerKey" => $customerKey, "username" => "xyz@example.com");
/* JSON encode the request array to get JSON String */
$jsonRequestString = json_encode($jsonRequest);
$customerKeyHeader = "Customer-Key: " . $customerKey;
$timestampHeader = "Timestamp: " . number_format ( $currentTimeInMillis, 0, '', '' );
$authorizationHeader = "Authorization: " . $hashValue;
/* Initialize curl */
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/json", $customerKeyHeader,
$timestampHeader, $authorizationHeader));
curl_setopt($ch, CURLOPT_URL, $generateUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($ch, CURLOPT_VERBOSE, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonRequestString);
curl_setopt($ch, CURLOPT_POST, 1);
/* Calling the rest API */
$result = curl_exec($ch);
if (curl_errno($ch)) {
print curl_error($ch);
} else {
curl_close($ch);
}
/* If a valid response is received, get the JSON response */
$response = (array)json_decode($result);
$status = $response['statusCode'];
if($status == 'SUCCESS') {
return "SUCCESS";
} else {
return "FAILED: " . $response['message'];
}
}
?>