Mobile authentication
The mobile platform offers a two-factor authentication mechanism in a user-friendly and secure way. You can take advantage of mobile authentication to add a second authentication factor for your product, which can be used to improve the security of selected actions, like logging in to your website or accepting a payment transaction.
The mobile authentication feature is an extensive feature that has a number of different possibilities.
-
Push notifications: The user gets a push notification on their phone to alert them that a mobile authentication transaction is pending.
-
One-Time-Password (OTP): The user provides an OTP in order to confirm a mobile authentication transaction. Since the OTP is long, it is likely that the OTP is transformed into a QR code and the user scans this code with their mobile device.
Before mobile authentication can be used, you must configure the IDAAS-core to support this functionality. When the IDAAS-core is configured, you can enroll and handle mobile authentication requests using the Android SDK.
Enrollment
The enrollment is split up into two different steps:
-
Mobile authentication enrollment enables the basic mobile authentication feature that allows handling OTP requests.
-
Push mobile authentication enrollment enables mobile authentication using push messages.
During the enrollment process the Android SDK generates and exchanges PGP keys with the IDAAS-core. This allows to secure and authenticate all mobile authentication related communication. This step is required upfront whenever the users would like to use mobile authentication using OTP or push.
To check if a user profile has already enrolled for the mobile authentication (and their PGP keys are stored on the device), the Android SDK exposes the method: UserClient#isUserEnrolledForMobileAuth(UserProfile userProfile)
.
Note
PGP keys can be revoked by the Android SDK if they are malformed or any kind of security issue is discovered. It is recommended you check if the user is already registered for mobile authentication before attempting to register the user for mobile authentication.
Example code: to initialize mobile authentication enrollment for the currently authenticated user
public void enrollMobileAuthentication() {
final OneginiMobileAuthEnrollmentHandler mobileAuthEnrollmentHandler = new OneginiMobileAuthEnrollmentHandler() {
@Override
public void onSuccess() {
showToast("Mobile authentication enabled");
}
@Override
public void onError(final OneginiMobileAuthEnrollmentError error) {
@OneginiMobileAuthEnrollmentError.MobileAuthEnrollmentErrorType final int errorType = error.getErrorType();
if (errorType == OneginiMobileAuthEnrollmentError.DEVICE_DEREGISTERED) {
new DeregistrationUtil(SettingsActivity.this).onDeviceDeregistered();
}
showToast("Mobile authentication error - " + error.getMessage());
}
};
OneginiSDK.getOneginiClient(this).getUserClient().enrollUserForMobileAuth(mobileAuthEnrollmentHandler);
}
Request handling
In order to handle mobile authentication requests, the user needs to be enrolled for mobile authentication. To verify if the user is already enrolled, you should use the UserClient#isUserEnrolledForMobileAuth(UserProfile userProfile)
method.
The Android SDK is capable of handling two types of mobile authentication requests. For more information on handling each mobile authentication type, refer to Push and OTP.
Mobile authentication with push
Two-factor authentication can be implemented using FCM push notifications. Confirmation can be done using a simple Accept button, PIN, biometrics, or a custom authenticator. All transaction information is encrypted and no sensitive information is sent through FCM.
To configure push mobile authentication, you need to set up FCM in the Firebase Console and enable the feature in the IDAAS-core.
In order to use mobile authentication with push notifications, the device has to support Google Play Services. It's your responsibility to check if push notifications are supported on the device. When push notifications are available on the device, the app should fetch the Firebase instance token, which is used as a push token during the mobile authentication with push enrollment. Refer to the Google documentation on how to obtain this Firebase instance token.
All of the FCM communication must be handled by your application. This includes fetching the Firebase instance token. The reason why this responsibility is in the app is that one app can only have one Firebase instance token. This allows the application to support more push messaging features besides mobile authentication provided by the Android SDK.
The entire push mobile authentication process can be described as follows. In this flow we call the initiator of the mobile authentication request portal.
In this diagram the application has the following responsibilities:
-
Parsing and passing the data message received from FCM to the Android SDK
-
Responding to authentication requests using the
*RequestHandler
interfaces-
Displaying a dialog to the user when the authentication challenge is received
-
Sending the users' response back to the Android SDK
-
-
Handling the completion of the mobile authentication request
Push token enrollment
The FCM SDK generates a registration token used for communication with the backend. The token has to be passed to the Android SDK via the OneginiClient#enrollUserForMobileAuthWithPush
method.
Example code: initialize mobile authentication with push enrollment for the currently authenticated user
final UserClient userClient = OneginiSDK.getOneginiClient(context).getUserClient();
userClient.enrollUserForMobileAuthWithPush("myRegistrationId", new OneginiMobileAuthWithPushEnrollmentHandler() {
@Override
public void onSuccess() {
showToast("Mobile authentication enabled");
}
@Override
public void onError(final OneginiMobileAuthWithPushEnrollmentError error) {
@OneginiMobileAuthWithPushEnrollmentError.MobileAuthWithPushEnrollmentErrorType final int errorType = error.getErrorType();
if (errorType == OneginiMobileAuthWithPushEnrollmentError.DEVICE_DEREGISTERED) {
new DeregistrationUtil(SettingsActivity.this).onDeviceDeregistered();
}
showToast("Mobile authentication error - " + error.getMessage());
}
);
Updating a push token
The FCM token can be rotated after initial startup. It is the applications responsibility to notify the Android SDK that the token has changed. To do so, call the DeviceClient#refreshMobileAuthPushToken
method with the new refresh token. The method updates the token for all users of the app that have been enrolled for push and it doesn't require any user authentication. The method will return an error if no user is registered for mobile authentication with push.
Example code: update the push token for all users
final OneginiRefreshMobileAuthPushTokenHandler handler = new OneginiRefreshMobileAuthPushTokenHandler() {
@Override
public void onSuccess() {
// method called when the token has been updated
}
@Override
public void onError(final OneginiRefreshMobileAuthPushTokenError error) {
// method called when the token update has failed
}
};
OneginiSDK.getOneginiClient(context).getDeviceClient().refreshMobileAuthPushToken(newRefreshToken, handler);
Validating user is registered
To check if a particular user profile has already enrolled for mobile authentication with push, the Android SDK exposes the method: UserClient#isUserEnrolledForMobileAuthWithPush(UserProfile userProfile)
.
Note
This method checks if the user has enrolled for push enrollment in the past and that the user still has valid PGP keys stored on the device. This method does not check if the Firebase instance token used for enrollment with FCM is still valid.
Request handling
Passing the mobile authentication request to the Android SDK
The application is responsible for handling notifications from FCM. The Mobile Identity module uses a data message type of FCM notifications. To read more about FCM message types, follow the FCM documentation.
When the application can receive FCM messages, it should parse the incoming push object (RemoteMessage
) to determine if it contains the mobile authentication request. The request is a JSON object that contains the following properties:
og_transaction_id
is a unique identifier for each mobile authentication request.og_message
is the message specified by the portal when initializing the request.og_profile_id
is the ID of the user profile for which the request was sent.
Example code: body of the Mobile Authentication Request
{"og_transaction_id":"8fdd1d7a-6a9a-487a-b7bb-24e167569ab6","og_message":"Lorem ipsum","og_profile_id":"VGLDTJ"}
Valid requests should be parsed to theOneginiMobileAuthWithPushRequest
class, which has corresponding mandatory properties (transaction id
, message
, user profile id
).
Tip
The class also defines the mapping between the JSON properties and the class using @SerializedName
annotations. The recommended way to parse the incoming message into the OneginiMobileAuthWithPushRequest
is to use the Google Gson parser and let it use the annotations to properly deserialize the JSON.
Example code: OneginiMobileAuthWithPushRequest
public class OneginiMobileAuthWithPushRequest {
@SerializedName(value="transaction_id", alternate="og_transaction_id")
private final String transactionId;
@SerializedName(value="message", alternate="og_message")
private final String message;
@SerializedName(value="profile_id", alternate="og_profile_id")
private final String userProfileId;
@SerializedName("timestamp")
private final long timestamp;
@SerializedName("time_to_live_seconds")
private final int timeToLiveSeconds;
public OneginiMobileAuthWithPushRequest(final String transactionId, final String message, final String userProfileId) {
this(transactionId, message, userProfileId, 0, 0);
}
public OneginiMobileAuthWithPushRequest(final String transactionId, final String message, final String userProfileId, final long timestamp, final int ttl) {
// ...
}
// ...
}
Example code: RemoteMessage parsing
@Override
public void onMessageReceived(final RemoteMessage message) {
final OneginiMobileAuthWithPushRequest mobileAuthWithPushRequest = parseOneginiMobileAuthRequest(message);
if (mobileAuthWithPushRequest != null) {
// handle the mobile authentication request using the Android SDK
}
}
@Nullable
private OneginiMobileAuthWithPushRequest parseOneginiMobileAuthRequest(final RemoteMessage message) {
if (message == null || message.getData() == null) {
return null;
}
final String json = message.getData().get("content");
try {
return gson.fromJson(json, OneginiMobileAuthWithPushRequest.class);
} catch (final JsonSyntaxException e) {
return null;
}
}
When the mobile authentication request is successfully parsed, you can pass it to the Android SDK to handle it using the handleMobileAuthWithPushRequest()
method on the UserClient
instance:
public void handleMobileAuthWithPushRequest(@NonNull final OneginiMobileAuthWithPushRequest oneginiMobileAuthWithPushRequest,
@NonNull final OneginiMobileAuthenticationHandler mobileAuthenticationHandler);
At which time the Android SDK will use OneginiMobileAuthenticationHandler
to perform the request and end in one of the two methods of OneginiMobileAuthenticationHandler
.
void onSuccess
: mobile authentication was successfulvoid onError
: mobile authentication failed
Tip
In the event the user rejects or denies a mobile authentication request, the onError
method will be called with error type ACTION_CANCELED
.
Example code: push notification handling
private void handleMobileAuthenticationRequest(final OneginiMobileAuthWithPushRequest request) {
OneginiSDK.getOneginiClient(this).getUserClient().handleMobileAuthWithPushRequest(request, new OneginiMobileAuthenticationHandler() {
@Override
public void onSuccess(final CustomInfo customInfo) {
// Method called when mobile authentication request was successful.
}
@Override
public void onError(final OneginiMobileAuthenticationError oneginiMobileAuthenticationError) {
// Method called when mobile authentication request has failed.
}
});
}
Pending mobile authentication request
Mobile authentication requests that were sent from the server using FCM, but were not delivered to the Android SDK are considered pending requests. In the event of pending requests, you can call the Android SDK for a list of pending mobile authentication requests.
The Android SDK allows you to access the pending mobile authentication requests using OneginiMobileAuthWithPushRequest
class. The class methods can be used to return the following information:
public String getTransactionId()
returns a unique identifier for each mobile authentication request.public String getMessage()
returns the message specified by the portal when initializing the mobile authentication request.public String getUserProfileId
returns the ID of the user profile for which the mobile authentication request was sent.public long getTimestamp()
returns an epoch or unix timestamp representing the date when the request was created.public int getTimeToLiveSeconds()
returns the maximum lifespan of a message (Time-To-Live) in seconds.
If there are no pending mobile authentication requests, the returned set will be empty.
Example code: for fetching pending mobile authentication requests
OneginiSDK.getOneginiClient(this).getUserClient().getPendingMobileAuthWithPushRequests(new OneginiPendingMobileAuthWithPushRequestsHandler() {
@Override
public void onSuccess(final Set<OneginiMobileAuthWithPushRequest> set) {
// show pending mobile authentication requests
}
@Override
public void onError(final OneginiPendingMobileAuthWithPushRequestError oneginiPendingMobileAuthWithPushRequestError) {
// show possible error
}
});
Denying mobile authentication request
To allow users to deny and delete authentication requests without invoking request handling, you can use the handleMobileAuthWithPushRequest()
method.
Example code: for denying pending mobile authentication request
OneginiSDK.getOneginiClient(context).getUserClient().denyMobileAuthWithPushRequest(oneginiMobileAuthWithPushRequest, new OneginiDenyMobileAuthWithPushRequestHandler() {
@Override
public void onSuccess() {
// update the list of pending mobile authentication requests
}
@Override
public void onError(final OneginiDenyMobileAuthWithPushRequestError oneginiDenyMobileAuthWithPushRequestError) {
// show possible error
}
});
Types of mobile authentication with push
You can configure different types of mobile authentication with push. The available types of authentication include: Push, Push with PIN, Push with biometrics, and Push with custom authenticator.
The types of mobile authentication must be configured before you can use them. You can define multiple types with the same authentication method. Each type of authentication requires a proper handler implementation in the Android SDK.
Push
Push allows users to accept or deny a request. To support the push type in your app, you need to implement the OneginiMobileAuthWithPushRequestHandler
interface and set its instance during the Android SDK initialization step by calling setMobileAuthWithPushRequestHandler(OneginiMobileAuthWithPushRequestHandler handler)
method on OneginiClientBuilder
. Additionally, you need to handle all interface methods in order to show or hide the user interface wit, for example, buttons allowing to accept or deny request.
Example code: how to set OneginiMobileAuthWithPushRequestHandler
You need to implement both startAuthentication
and finishAuthentication
methods:
-
startAuthentication(final OneginiMobileAuthenticationRequest oneginiMobileAuthenticationRequest, final OneginiAcceptDenyCallback oneginiAcceptDenyCallback)
is called when a new mobile authentication request is received.-
The first parameter is a
OneginiMobileAuthenticationRequest
object that contains the message you should present to the user and aUserProfile
object that specifies the request's receiver. -
The second parameter is a callback object that you should use when the user accepts or denies the request, by calling
acceptAuthenticationRequest
ordenyAuthenticationRequest
respectively.
-
-
finishAuthentication
method is called after the end of processing the user response to the request.
new OneginiClientBuilder(applicationContext, createPinRequestHandler, pinAuthenticationRequestHandler)
.setMobileAuthWithPushRequestHandler(new MobileAuthenticationRequestHandler(applicationContext))
.build();
Example code: how to implement OneginiMobileAuthWithPushRequestHandler
public class MobileAuthenticationRequestHandler implements OneginiMobileAuthWithPushRequestHandler {
public static OneginiAcceptDenyCallback CALLBACK;
private final Context context;
private String userProfileId;
private String message;
public MobileAuthenticationRequestHandler(final Context context) {
this.context = context;
}
@Override
public void startAuthentication(final OneginiMobileAuthenticationRequest oneginiMobileAuthenticationRequest,
final OneginiAcceptDenyCallback oneginiAcceptDenyCallback) {
CALLBACK = oneginiAcceptDenyCallback;
userProfileId = oneginiMobileAuthenticationRequest.getUserProfile().getProfileId();
message = oneginiMobileAuthenticationRequest.getMessage();
notifyActivity(COMMAND_START);
}
@Override
public void finishAuthentication() {
final Intent intent = prepareActivityIntent(COMMAND_FINISH);
context.startActivity(intent);
}
private Intent prepareActivityIntent(final String command) {
final Intent intent = new Intent(context, MobileAuthenticationActivity.class);
intent.putExtra(EXTRA_COMMAND, command);
intent.putExtra(EXTRA_MESSAGE, message);
intent.putExtra(EXTRA_USER_PROFILE_ID, userProfileId);
intent.addFlags(FLAG_ACTIVITY_NEW_TASK);
return intent;
}
}
Push with PIN
Push with PIN requires users to enter their PIN to accept the mobile authentication request. To support the push with PIN type, you need to implement the OneginiMobileAuthWithPushPinRequestHandler
interface and set its instance during the Android SDK initialization step by calling the setMobileAuthWithPushPinRequestHandler(OneginiMobileAuthWithPushPinRequestHandler handler)
method on the OneginiClientBuilder
. You also need to handle all interface methods in order to show or hide the user interface with a PIN input and buttons allowing to accept or deny a request.
You need to implement the startAuthentication
, onNextAuthenticationAttempt
and finishAuthentication
methods:
-
startAuthentication(final OneginiMobileAuthenticationRequest oneginiMobileAuthenticationRequest, final OneginiPinCallback oneginiPinCallback, final AuthenticationAttemptCounter attemptCounter, final OneginiMobileAuthenticationError oneginiMobileAuthenticationError)
the app receives new mobile authentication request.-
The first parameter is a
OneginiMobileAuthenticationRequest
object that contains the message you should present to the user and aUserProfile*
object that specifies the request's receiver. -
The second parameter is a callback object you should use when the user accepts or denies an incoming request by calling:
acceptAuthenticationRequest(pinEnteredByUser)
ordenyAuthenticationRequest
respectively. -
The third parameter is an
AuthenticationAttemptCounter
that holds information about failed, remaining, and max PIN attempts. -
The last parameter is an optional error that will be non-null when fallback to PIN was triggered by an error.
onNextAuthenticationAttempt(final AuthenticationAttemptCounter attemptCounter)
is called when the user entered the wrong PIN. TheattemptCounter
param object gives you the information about failed attempts count viagetFailedAttempts()
method indicating how many times the wrong PIN was entered during the current authentication attempt. In the same way, you can get max attempts with thegetMaxAttempts()
method and remaining attempts withgetRemainingAttempts()
. You can display those values to the user.
-
-
finishAuthentication
is called after end of processing the user response to the request.
Example code: how to implement OneginiMobileAuthWithPushPinRequestHandler
public class MobileAuthenticationPinRequestHandler implements OneginiMobileAuthWithPushPinRequestHandler {
public static OneginiPinCallback CALLBACK;
private final Context context;
private int failedAttemptsCount;
private int maxAttemptsCount;
private String message;
private String userProfileId;
public MobileAuthenticationPinRequestHandler(final Context context) {
this.context = context;
}
@Override
public void startAuthentication(final OneginiMobileAuthenticationRequest oneginiMobileAuthenticationRequest, final OneginiPinCallback oneginiPinCallback,
final AuthenticationAttemptCounter attemptCounter, final OneginiMobileAuthenticationError oneginiMobileAuthenticationError) {
CALLBACK = oneginiPinCallback;
message = oneginiMobileAuthenticationRequest.getMessage();
userProfileId = oneginiMobileAuthenticationRequest.getUserProfile().getProfileId();
failedAttemptsCount = maxAttemptsCount = 0;
notifyActivity(COMMAND_START);
}
@Override
public void onNextAuthenticationAttempt(final AuthenticationAttemptCounter attemptCounter) {
failedAttemptsCount = attemptCounter.getFailedAttempts();
maxAttemptsCount = attemptCounter.getMaxAttempts();
notifyActivity(COMMAND_START);
}
@Override
public void finishAuthentication() {
notifyActivity(COMMAND_FINISH);
}
private void notifyActivity(final String command) {
final Intent intent = prepareActivityIntent(command);
context.startActivity(intent);
}
private Intent prepareActivityIntent(final String command) {
final Intent intent = new Intent(context, MobileAuthenticationPinActivity.class);
intent.putExtra(EXTRA_COMMAND, command);
intent.putExtra(EXTRA_MESSAGE, message);
intent.putExtra(EXTRA_USER_PROFILE_ID, userProfileId);
intent.putExtra(EXTRA_FAILED_ATTEMPTS_COUNT, failedAttemptsCount);
intent.putExtra(EXTRA_MAX_FAILED_ATTEMPTS, maxAttemptsCount);
intent.addFlags(FLAG_ACTIVITY_NEW_TASK);
return intent;
}
}
Push with biometrics
Push with biometrics requires the user to scan their fingerprint to successfully accept the mobile authentication request. To support the push with biometrics type, you need to implement the OneginiMobileAuthWithPushBiometricRequestHandler
interface and set its instance during the Android SDK initialization step by calling the setMobileAuthWithPushBiometricRequestHandler(OneginiMobileAuthWithPushBiometricRequestHandler mobileAuthenticationBiometricRequestHandler)
method on the OneginiClientBuilder
. You also need to handle all interface methods to show or hide the biometric prompt and buttons, allowing the user to accept or deny the mobile authentication request as well as perform a fallback to PIN.
You need to implement the startAuthentication
, onNextAuthenticationAttempt
and finishAuthentication
methods:
-
startAuthentication(final OneginiMobileAuthenticationRequest oneginiMobileAuthenticationRequest, final OneginiPinCallback oneginiPinCallback, final AuthenticationAttemptCounter attemptCounter, final OneginiMobileAuthenticationError oneginiMobileAuthenticationError)
the app receives new mobile authentication request.-
The first parameter is a
OneginiMobileAuthenticationRequest
object that contains the message you should present to the user and aUserProfile*
object that specifies the request's receiver. -
The second parameter is a callback object you should use when the user accepts or denies an incoming request by calling:
acceptAuthenticationRequest(pinEnteredByUser)
ordenyAuthenticationRequest
respectively. -
The third parameter is an
AuthenticationAttemptCounter
that holds information about failed, remaining, and max PIN attempts. -
The last parameter is an optional error that will be non-null when fallback to PIN was triggered by an error.
onNextAuthenticationAttempt(final AuthenticationAttemptCounter attemptCounter)
is called when the user entered the wrong PIN. TheattemptCounter
param object gives you the information about failed attempts count via thegetFailedAttempts()
method indicating how many times the wrong PIN was entered during the current authentication attempt. In the same way, you can get the max attempts with thegetMaxAttempts()
method and remaining attempts withgetRemainingAttempts()
. You can display those values to the user.
-
-
finishAuthentication
is called after the end of processing the user response to the request.
Example code: how to implement OneginiMobileAuthWithPushBiometricRequestHandler
public class MobileAuthenticationBiometricRequestHandler implements OneginiMobileAuthWithPushBiometricRequestHandler {
public static OneginiBiometricCallback CALLBACK;
public static BiometricPrompt.CryptoObject CRYPTO_OBJECT;
private final Context context;
private String userProfileId;
private String message;
public MobileAuthenticationBiometricRequestHandler(final Context context) {
this.context = context;
}
@Override
public void startAuthentication(@NonNull OneginiMobileAuthenticationRequest oneginiMobileAuthenticationRequest,
@NonNull BiometricPrompt.CryptoObject cryptoObject,
@NonNull OneginiBiometricCallback oneginiBiometricCallback) {
CALLBACK = oneginiBiometricCallback;
CRYPTO_OBJECT = cryptoObject;
userProfileId = oneginiMobileAuthenticationRequest.getUserProfile().getProfileId();
message = oneginiMobileAuthenticationRequest.getMessage();
notifyActivity(COMMAND_ASK_TO_ACCEPT_OR_DENY);
}
@Override
public void finishAuthentication() {
notifyActivity(COMMAND_FINISH);
}
private void notifyActivity(final String command) {
final Intent intent = new Intent(context, MobileAuthenticationBiometricActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(EXTRA_COMMAND, command);
intent.putExtra(EXTRA_MESSAGE, message);
intent.putExtra(EXTRA_USER_PROFILE_ID, userProfileId);
context.startActivity(intent);
}
}
Push with custom authenticator
Push with custom authenticator allows users to authenticate by accepting a request from a custom authenticator. To support push with custom authenticator, you first need to implement custom authentication. After that, you need to implement the OneginiMobileAuthWithPushCustomRequestHandler
interface and set its instance during the Android SDK initialization step by calling the public OneginiClientBuilder setMobileAuthWithPushCustomRequestHandler(final OneginiMobileAuthWithPushCustomRequestHandler mobileAuthenticationCustomRequestHandler)
method on the OneginiClientBuilder
. You also need to handle all interface methods in order to show or hide buttons allowing the user to accept or deny the mobile authentication request or perform a fallback to PIN.
You need to implement both startAuthentication
and finishAuthentication
methods:
-
startAuthentication(final OneginiMobileAuthenticationRequest oneginiMobileAuthenticationRequest, final OneginiAcceptDenyCallback oneginiAcceptDenyCallback)
is called when a new mobile authentication request is received.-
The first parameter is a
OneginiMobileAuthenticationRequest
object that contains the message you should present to the user and aUserProfile
object that specifies the request's receiver. -
The second parameter is a callback object that you should use when the user accepts or denies the request, by calling
acceptAuthenticationRequest
ordenyAuthenticationRequest
respectively.
-
-
finishAuthentication
method is called after the end of processing the user response to the request.
Example code: how to implement OneginiMobileAuthWithPushCustomRequestHandler
public class MobileAuthenticationBasicCustomRequestHandler implements OneginiMobileAuthWithPushCustomRequestHandler {
public static OneginiCustomCallback CALLBACK;
private final Context context;
private String userProfileId;
private String message;
public MobileAuthenticationBasicCustomRequestHandler(final Context context) {
this.context = context;
}
@Override
public void startAuthentication(final OneginiMobileAuthenticationRequest oneginiMobileAuthenticationRequest,
final OneginiCustomCallback oneginiCustomCallback) {
CALLBACK = oneginiCustomCallback;
userProfileId = oneginiMobileAuthenticationRequest.getUserProfile().getProfileId();
message = oneginiMobileAuthenticationRequest.getMessage();
notifyActivity(COMMAND_START);
}
@Override
public void finishAuthentication() {
notifyActivity(COMMAND_FINISH);
}
private void notifyActivity(final String command) {
final Intent intent = prepareActivityIntent(command);
context.startActivity(intent);
}
private Intent prepareActivityIntent(final String command) {
final Intent intent = new Intent(context, MobileAuthenticationCustomActivity.class);
intent.putExtra(EXTRA_COMMAND, command);
intent.putExtra(EXTRA_USER_PROFILE_ID, userProfileId);
intent.putExtra(EXTRA_MESSAGE, message);
intent.addFlags(FLAG_ACTIVITY_NEW_TASK);
return intent;
}
}
Push error scenarios
When push with a specific authenticator is received, the Android SDK tries to use the exact authenticator that was selected. However, during the authentication attempt some errors can occur. Those errors can be authenticator specific or not. For example, if mobile authentication with fingerprint was requested, but the user fails to provide the correct fingerprint several times, such an authenticator error will trigger a fallback to PIN authenticator. In such case, the Android SDK will start a new mobile authentication with PIN, like described above, while the last param of the startAuthentication()
method will contain a non-null error object containing the error details. That's the opposite to a regular PIN authentication request (a request that was started by incoming mobile authentication with PIN) when the error object is null.
In case of errors that are not authenticator-specific, the Android SDK will not trigger PIN authentication, but it will return the error immediately on the OneginiMobileAuthenticationHandler#onError()
. For example, if mobile authentication with custom authenticator was received, but the user has lost their internet connection, the Android SDK will return this error to the app without triggering the fallback to PIN authentication.
Mobile authentication with OTP
The mobile security platform offers the ability of mobile authentication with a One-Time Password (OTP). Mobile authentication with OTP provides users an easy and secure way for two-factor authentication or single-factor authentication where no passwords are required. All of the communication stays between app, web application, and mobile security platform.
To use mobile authentication with OTP, you have to set it up in the IDAAS-core. Each user of the app has to perform the mobile authentication enrollment in order to enable the functionality.
To verify if the user is already registered for mobile authentication you can use the UserClient#isUserEnrolledForMobileAuth(UserProfile userProfile)
method.
Request handler
The entire OTP mobile authentication process from can be described as follows. In this flow we call the initiator of the mobile authentication request portal:
Setting up the OTP request handler
For OTP authentication, the application has the following responsibilities:
-
Passing the mobile authentication request received from the initiator to the Android SDK
-
Responding to the confirmation request
-
(optionally ) Displaying a dialog to the user when their confirmation is required
- Sending the user response back to the Android SDK
-
-
Handling completion of the mobile authentication request
To support mobile authentication with OTP in your app, you need to implement the OneginiMobileAuthOtpRequestHandler
interface and set its instance during the Android SDK initialization step by calling the setMobileAuthenticationOtpRequestHandler(OneginiMobileAuthOtpRequestHandler handler)
method on OneginiClientBuilder
. Then you need to handle all interface methods in order to show or hide the user interface with, for example, buttons allowing to accept or deny request.
You need to implement both startAuthentication
and finishAuthentication
methods:
-
startAuthentication(final OneginiMobileAuthenticationRequest oneginiMobileAuthenticationRequest, final OneginiAcceptDenyCallback oneginiAcceptDenyCallback)
is called when a new mobile authentication request is received.-
The first parameter is a
OneginiMobileAuthenticationRequest
object that contains the message you should present to the user and aUserProfile
object that specifies the request's receiver. -
The second parameter is a callback object that you should use when the user accepts or denies the request, by calling
acceptAuthenticationRequest
ordenyAuthenticationRequest
respectively.
-
-
finishAuthentication
method is called after the end of processing the user response to the request.
Example code: how to set the OneginiMobileAuthOtpRequestHandler
new OneginiClientBuilder(applicationContext, createPinRequestHandler, pinAuthenticationRequestHandler)
.setMobileAuthenticationOtpRequestHandler(new MobileAuthOtpRequestHandler())
.build();
Example code: how to implement the OneginiMobileAuthOtpRequestHandler
public class MobileAuthOtpRequestHandler implements OneginiMobileAuthOtpRequestHandler {
@Override
public void startAuthentication(final OneginiMobileAuthenticationRequest oneginiMobileAuthenticationRequest,
final OneginiAcceptDenyCallback oneginiAcceptDenyCallback) {
// You can simply accept the request like we do or use the OneginiMobileAuthenticationRequest object to display some info to the end-user and ask for his permission.
oneginiAcceptDenyCallback.acceptAuthenticationRequest();
}
@Override
public void finishAuthentication() {
// In case you displayed a dialog you can close the dialog here.
}
}
Passing the OTP request to the Android SDK
To trigger mobile authentication with OTP, a user has to be authenticated (logged in to your app). After that condition is satisfied and the user is enrolled for mobile authentication, you can call the OneginiClient#UserClient#handleMobileAuthWithOtp(String otpCode, OneginiMobileAuthWithOtpHandler mobileAuthWithOtpHandler)
method.
- The first argument is the OTP received from your web application.
-
The second argument is the
OneginiMobileAuthWithOtpHandler
interface that contains two methods that you should react to:-
onSuccess()
is called when mobile authentication with OTP succeeded. -
onError(OneginiMobileAuthWithOtpError error)
is called when an error occurred during mobile authentication with OTP. Check theOneginiMobileAuthWithOtpError
error object to learn about the reason for failure. You can check an error type and message by calling thegetErrorType()
andgetMessage()
methods respectively on the error object.
-
Example code: how to trigger authentication with OTP
final OneginiMobileAuthWithOtpHandler oneginiMobileAuthWithOtpHandler = new OneginiMobileAuthWithOtpHandler() {
@Override
public void onSuccess() {
showToast("Mobile auth with OTP succeeded");
}
@Override
public void onError(final OneginiMobileAuthWithOtpError oneginiMobileAuthWithOtpError) {
showToast("Mobile auth with OTP error:" + oneginiMobileAuthWithOtpError.getMessage());
}
};
final UserClient userClient = OneginiSDK.getOneginiClient(activity.getApplicationContext()).getUserClient();
userClient.handleMobileAuthWithOtp(otpCode, oneginiMobileAuthWithOtpHandler);