Mobile authentication with Push

Two factor authentication can be implemented using FCM push notifications. It's a very secure and user friendly way of authentication. You can use this feature to allow users to confirm their transactions. Confirmation can be done using a simple Accept button, PIN, Fingerprint or a custom authenticator. All transaction information is encrypted and no sensitive information is sent through FCM.

Configuration

First you need to set up FCM in the Firebase Console and the Token Server as described in the Token Server documentation.

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. Once 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. Please refer to the Google documentation on how to obtain this Firebase instance token. In order to use push mobile authentication with additional fingerprint verification you need to make sure that device has a fingerprint scanner and it fulfills all fingerprint requirements.

Enrollment

After you've set up FCM and enrolled the used for mobile authentication, you need to perform one additional enrollment step to allow your users to perform mobile authentication with push notifications. The user can be enrolled on only a single device (application instance) at a time. If the user has two mobile devices on which the application is installed, the user can only enroll for mobile authentication with push on one of these devices. 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 app to support more push messaging features besides mobile authentication provided the SDK.

Push token enrollment

As mentioned on FCM docs the FCM SDK generates a registration token used for communication with backend. The token has to be passed to the Onegini SDK via the OneginiClient#enrollUserForMobileAuthWithPush method.

Example code to 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());
    }
);

Push token update

The FCM token could be rotated after initial startup. When this happens it's the app responsibility to notify the Onegini SDK that the token has changed. To do so, call the DeviceClient#refreshMobileAuthPushToken method with the new refresh token.

Example code to 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);

Please note, that:

  • 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

Check if user is enrolled

To check if a particular user profile has already enrolled for mobile authentication with push the SDK exposes the method: UserClient#isUserEnrolledForMobileAuthWithPush(UserProfile userProfile). Please note, that 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. However, the method doesn't have an ability to check if the Firebase instance token used for enrollment with FCM is still valid or not.

Request handling

Once a user is enrolled, he/she should be able to receive push mobile authentication requests. To verify if the user is already enrolled for push mobile authentication, you should use the UserClient#isUserEnrolledForMobileAuthWithPush(UserProfile userProfile) method.

The entire push mobile authentication process can be described as follows. In this flow we call the initiator of the mobile authentication request 'portal':

1. Portal -> Token Server: Initialize mobile authentication.
2. Token Server -> FCM: Send the push notification.
3. FCM -> Token Server: Push notification delivery report.
4. Token Server -> Portal: Identifier of the initialized mobile authentication transaction.
5. FCM -> APP: deliver push notification.
6. APP -> SDK: parse the push notification and delegate handling of the mobile authentication reqeust to the SDK.
7. SDK -> Token Server: Fetch PGP encrypted message from server.
8. Token Server -> SDK: Base64 encoded PGP encrypted authentication data.
9. SDK -> APP: The push message is decrypted and the SDK triggers a request handler so the app can show 
        a dialogue to the end-user.
10. APP -> SDK: Application responds with the authentication result.
11. SDK -> Token Server: The authentication result is send encrypted to the Token Server.
12. Token Server -> SDK: If the used push type requires feedback on the result e.g. pin usage 
        the result is communicated back to the SDK which will optionally perform a retry.
13. Token Server -> Portal: A callback is sent to inform the portal about the mobile 
        authentication result.

As you can see from the diagram above, the application has the following responsibilities:

  1. Parsing and passing the data message received from FCM to the SDK
  2. Responding to authentication requests using the *RequestHandler interfaces
    1. Displaying a dialog to the end-user when the authentication challenge is received
    2. Sending the users' response back to the SDK
  3. Handling the completion of the mobile authentication request

The Following paragraphs explain those steps and show how the responsibilities mentioned above can be implemented.

Passing the mobile authentication request to the SDK

The Token Server uses a data message type of FCM notifications. This means that the app itself is responsible for handling the notification received from FCM. To read more about FCM message types, please follow the FCM documentation.

When the app is capable to receive incoming FCM messages it should parse the incoming push object (RemoteMessage) in order to decide if it contains the Onegini Mobile Authentication Request. This allows the app to support multiple types of push notifications next to the mobile authentication request. The request is a JSON object which contains the following properties:

  • og_transaction_id an unique identifier for each mobile authentication request
  • og_message the message specified by the portal when initializing the request
  • og_profile_id the ID of the user profile for which the request was sent

Example body of the Mobile Authentication Request

{"og_transaction_id":"8fdd1d7a-6a9a-487a-b7bb-24e167569ab6","og_message":"Lorem ipsum","og_profile_id":"VGLDTJ"}

The valid request should be parsed to the OneginiMobileAuthWithPushRequest class, which has corresponding mandatory properties (transaction id, message, user profile id) with two optional properties (timestamp and ttl) that are not used in this case.

The 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) {
    // ...
  }

  // ...
}

As you can see, 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 simply use the annotations to properly deserialize the JSON.

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 Onegini 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 was successfully parsed, you can pass it to the SDK in order to handle it using handleMobileAuthWithPushRequest() method on the UserClient instance:

public void handleMobileAuthWithPushRequest(@NonNull final OneginiMobileAuthWithPushRequest oneginiMobileAuthWithPushRequest,
                                            @NonNull final OneginiMobileAuthenticationHandler mobileAuthenticationHandler);

Then the SDK will use OneginiMobileAuthenticationHandler to perform the request and end in one of the two methods of OneginiMobileAuthenticationHandler:

  • Mobile Authentication was successful

    void onSuccess(CustomAuthenticatorInfo customAuthenticatorInfo);
    
  • Mobile Authentication failed due to an error

    void onError(OneginiMobileAuthenticationError error);
    

    Please note, that the user has an ability to deny incoming mobile authentication request. In such case the onError method will be called with an ACTION_CANCELED error type.

For more info on error handling see the error handling topic guide.

Example code push notification handling

  private void handleMobileAuthenticationRequest(final OneginiMobileAuthWithPushRequest request) {
    OneginiSDK.getOneginiClient(this).getUserClient().handleMobileAuthWithPushRequest(request, new OneginiMobileAuthenticationHandler() {
      @Override
      public void onSuccess(final CustomAuthenticatorInfo customAuthenticatorInfo) {
        // Method called when mobile authentication request was successful.
      }

      @Override
      public void onError(final OneginiMobileAuthenticationError oneginiMobileAuthenticationError) {
        // Method called when mobile authentication request has failed.
      }
    });
  }

Please note that CustomAuthenticatorInfo is an optional param that can be non null only when custom authenticator was used.

Pending mobile authentication request

Mobile authentication requests that were send from the server using FCM, but were not delivered to the SDK are considered as "pending" requests. This can happen when the message send through FCM was not delivered yet. Another scenario is when the app has received the message but didn't pass it to the handleMobileAuthWithPushRequest() method yet - i.e. the app has created a notification to the user instead, but he didn't answer it yet.

In both cases you can call the SDK for a list of pending mobile authentication requests. You can check the list on the app startup and start the pending requests handling regardless if user has ignored notifications on the notification bar or FCM has failed to deliver the message on time.

The pending mobile authentication request is also represented by the OneginiMobileAuthWithPushRequest class. The class has number of methods to return the following info:

  • public String getTransactionId() returns an 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/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

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
  }
});

In case when there are no pending mobile authentication requests for the device, the returned set will be empty.

Types of mobile authentication with push

You can configure different types of mobile authentication with push in the Token Server mobile authentication configuration. For every type you can choose between different methods of authentication. These are: Push, Push with PIN, Push with fingerprint and Push with custom authenticator. The types of for mobile authentication must be configured on the Token Server first before you can use them. You can define multiple types with the same authentication method. Each type of authentication need a proper handler implementation to be provided in the SDK builder, as described below.

Push

The first type of mobile authentication request, the most simple one, is Push. In this type user have possibility to simply accept or deny request. To support the Push type in your app you need to implement OneginiMobileAuthWithPushRequestHandler interface and set its instance during the SDK initialization step by calling setMobileAuthWithPushRequestHandler(OneginiMobileAuthWithPushRequestHandler handler) method on OneginiClientBuilder. Then you need to handle all interface methods in order to show/hide user interface with (for example) buttons allowing to accept or deny request.

Example how to set OneginiMobileAuthWithPushRequestHandler

new OneginiClientBuilder(applicationContext, createPinRequestHandler, pinAuthenticationRequestHandler)
  .setMobileAuthWithPushRequestHandler(new MobileAuthenticationRequestHandler(applicationContext))
  .build();

Example 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;
  }
}

You need to implement both startAuthentication and finishAuthentication methods:

  • startAuthentication(final OneginiMobileAuthenticationRequest oneginiMobileAuthenticationRequest, final OneginiAcceptDenyCallback oneginiAcceptDenyCallback) is called when new mobile authentication request is received. First parameter is OneginiMobileAuthenticationRequest object which contains message you should present to the user and UserProfile object that specifies request's receiver. The Second parameter is a callback object that you should use when user accepts or denies the request, by calling acceptAuthenticationRequest or denyAuthenticationRequest respectively.
  • finishAuthentication method is called after end of processing the user response to the request.

Push with PIN

The Second type of mobile authentication request is Push with PIN. In this type the user also have a possibility to accept or deny request. Comparing to simple Push the Push with PIN requires the user to enter his PIN in order to successfully accept the mobile authentication request. To support Push with PIN type you need to implement the OneginiMobileAuthWithPushPinRequestHandler interface and set its instance during 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/hide user interface with a PIN input and buttons allowing to accept or deny request.

Example 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;
  }
}

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. First parameter is OneginiMobileAuthenticationRequest object which contains message you should present to the end user and UserProfile object that specifies request's receiver. Second parameter is a callback object you should use when user accepts or denies incoming request by calling: acceptAuthenticationRequest(pinEnteredByUser) or denyAuthenticationRequest respectively. 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 in case when fallback to PIN was triggered by an error
  • onNextAuthenticationAttempt(final AuthenticationAttemptCounter attemptCounter) is called when user entered wrong pin. The attemptCounter param object gives you the information about failed attempts count via getFailedAttempts() method indicating how many times wrong PIN was entered during current authentication attempt. Same way you can get max attempts with getMaxAttempts() method and remaining attempts with getRemainingAttempts(). You can display those values to the user.
  • finishAuthentication is called after end of processing the user response to the request.

Push with fingerprint

The third type of mobile authentication request is Push with fingerprint. In this type the user also have a possibility to accept or deny request. The Push with fingerprint requires the user to scan his fingerprint in order to successfully accept the mobile authentication request. To support Push with fingerprint type you need to implement the OneginiMobileAuthWithPushFingerprintRequestHandler interface and set its instance during SDK initialization step by calling the setMobileAuthWithPushFingerprintRequestHandler(OneginiMobileAuthWithPushFingerprintRequestHandler mobileAuthenticationFingerprintRequestHandler) method on the OneginiClientBuilder. You also need to handle all interface methods in order to show/hide user interface with a fingerprint input and buttons allowing the end-user to accept or deny the mobile authentication request as well as perform a fallback to PIN.

Example how to implement OneginiMobileAuthWithPushFingerprintRequestHandler

public class MobileAuthenticationFingerprintRequestHandler implements OneginiMobileAuthWithPushFingerprintRequestHandler {

  public static OneginiFingerprintCallback CALLBACK;

  private final Context context;
  private String message;
  private String userProfileId;

  public MobileAuthenticationFingerprintRequestHandler(final Context context) {
    this.context = context;
  }

  @Override
  public void startAuthentication(final OneginiMobileAuthenticationRequest oneginiMobileAuthenticationRequest,
                                  final OneginiFingerprintCallback oneginiFingerprintCallback) {
    CALLBACK = oneginiFingerprintCallback;
    message = oneginiMobileAuthenticationRequest.getMessage();
    userProfileId = oneginiMobileAuthenticationRequest.getUserProfile().getProfileId();
    notifyActivity(COMMAND_ASK_TO_ACCEPT_OR_DENY);
  }

  @Override
  public void onNextAuthenticationAttempt() {
    notifyActivity(COMMAND_RECEIVED_FINGERPRINT);
  }

  @Override
  public void onFingerprintCaptured() {
    notifyActivity(COMMAND_SHOW_SCANNING);
  }

  @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, MobileAuthenticationFingerprintActivity.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);
    return intent;
  }
}

You need to implement the startAuthentication, onNextAuthenticationAttempt, onFingerprintCaptured and finishAuthentication methods:

  • startAuthentication(final OneginiMobileAuthenticationRequest oneginiMobileAuthenticationRequest, final OneginiFingerprintCallback oneginiFingerprintCallback) the app receives new mobile authentication request. First parameter is OneginiMobileAuthenticationRequest object which contains message you should present to the end user, UserProfile object that specifies request's receiver. Second parameter is a callback object you should use when user accepts or denies incoming request by calling: acceptAuthenticationRequest(pinEnteredByUser) or denyAuthenticationRequest respectively. It also contains fallbackToPin() method that should be used when user decides not to scan the fingerprint but use PIN.
  • onNextAuthenticationAttempt() is called when user's fingerprint scan was verified as invalid. Note that scanner will be blocked when used will scan too many his fingerprint too many times without success. This is controlled by Android SDK and the number of attempts might differ depending on device vendor. When the attempts limit will be reached SDK will automatically fallback to PIN authentication.
  • onFingerprintCaptured() is called when fingerprint was scanned but not yet verified. You can show an information to the user that the verification process just started.
  • finishAuthentication() is called after end of processing the user response to the request.

Push with custom authenticator

The fourth type of mobile authentication request is Push with custom authenticator. In this type the user also have a possibility to accept or deny request. In order to authenticate the push message, user has to perform authentication using custom authenticator. To support push with custom authenticator you first need to implement custom authentication as described in the custom authentication topic guide. After that you need to implement the OneginiMobileAuthWithPushCustomRequestHandler interface and set its instance during 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/hide buttons allowing the end-user to accept or deny the mobile authentication request or perform a fallback to PIN.

Example 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;
  }
}
  • startAuthentication(final OneginiMobileAuthenticationRequest oneginiMobileAuthenticationRequest, final OneginiCustomCallback oneginiCustomCallback) the app receives new mobile authentication request. First parameter is OneginiMobileAuthenticationRequest object which contains message you should present to the end user, UserProfile object that specifies request's receiver. Second parameter is a callback object you should use when user accepts or denies incoming request by calling: acceptAuthenticationRequest() or denyAuthenticationRequest() respectively. It also contains fallbackToPin() method that should be used when user decides not to use the custom authenticator but use PIN instead.
  • finishAuthentication() is called after end of processing the user response to the request.

Error scenarios

When push with a specific authenticator is received, the 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 user fails to provide the correct fingerprint several times, such authenticator error will trigger a fallback to pin authenticator. In such case the SDK will start 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 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 user has lost his internet connection, the SDK will return this error to the app without triggering the fallback to pin.