Authenticate user with fingerprint

Introduction

The SDK allows you to authenticate users with the fingerprint scanner (if available on the device). You can use it for both regular authentication as well as mobile authentication. Users will be able to scan their fingerprint as many times as the Android system will allow them to. If Android fingerprint API will return an error for any reason (for example when too many failed attempts was detected), the SDK will revoke fingerprint authentication and perform a fallback to PIN authentication.

Enabling fingerprint authentication

In order to enable fingerprint authentication for user you need to request a list of not yet registered authenticators with UserClient.getNotRegisteredAuthenticators(final UserProfile userProfile). This method can be used after user is authenticated and will return a set of OneginiAuthenticator that are possible to register. Then you can register chosen authenticator providing the authenticator's instance to UserClient.registerAuthenticator(final OneginiAuthenticator authenticator, final OneginiAuthenticatorRegistrationHandler handler) method, along with the handler that will inform you about success or failure of the registration process. If your device haven't met one of the requirements, the fingerprint authenticator won't be present on the list of authenticators.

Example code for registering a fingerprint authenticator

UserProfile authenticatedUserProfile = OneginiSDK.getOneginiClient(context).getUserClient().getAuthenticatedUserProfile();

OneginiAuthenticator fingerprintAuthenticator;
// to get the fingerprint authenticator
final Set<OneginiAuthenticator> notRegisteredAuthenticators = OneginiSDK.getOneginiClient(context).getUserClient().getNotRegisteredAuthenticators(authenticatedUserProfile);
for (final OneginiAuthenticator auth : notRegisteredAuthenticators) {
    if (auth.getType() == OneginiAuthenticator.FINGERPRINT) {
      // the fingerprint authenticator is available for registration
      fingerprintAuthenticator = auth;
    }
}

// fingerprint authentication is not always available
if (fingerprintAuthenticator == null) {
  return;
}

//to register the authenticator
OneginiSDK.getOneginiClient(context).getUserClient().registerAuthenticator(fingerprintAuthenticator, new OneginiAuthenticatorRegistrationHandler() {
    @Override
    public void onSuccess(final CustomInfo customInfo) {
      // successfully registered authenticator
    }

    @Override
    public void onError(final OneginiAuthenticatorRegistrationError oneginiAuthenticatorRegistrationError) {
      // handle different errors, below we mapped two of the possible errors that can occur
      @OneginiAuthenticatorRegistrationError.AuthenticatorRegistrationErrorType int errorType = error.getErrorType();
      if (errorType == OneginiAuthenticatorRegistrationError.USER_DEREGISTERED) {
        new DeregistrationUtil(SettingsAuthenticatorsActivity.this).onUserDeregistered(authenticatedUserProfile);
        startLoginActivity();
      } else if (errorType == OneginiAuthenticatorRegistrationError.DEVICE_DEREGISTERED) {
        new DeregistrationUtil(SettingsAuthenticatorsActivity.this).onDeviceDeregistered();
        startLoginActivity();
      }

      onErrorOccurred(position, error.getMessage());
    }
});

Note that registering a new authenticator doesn't make it a preferred authenticator to be used. By default preferred authenticator is PIN, so if you want to change it, you need to inform the SDK about it with UserClient.setPreferredAuthenticator(final OneginiAuthenticator auth) providing any registered authenticator.

Please note that CustomInfo is an optional param that will be always null during fingerprint authenticator registration.

Authentication handlers

The SDK provides two interfaces (OneginiFingerprintAuthenticationRequestHandler and OneginiMobileAuthWithPushFingerprintRequestHandler for respectively: regular and push authentication) that you can implement in your application to use the fingerprint authentication. Later you will need to provide them to OneginiClientBuilder instance as shown below:

Example code for supplying fingerprint auth request handlers to the SDK

OneginiClientBuilder(applicationContext, createPinRequestHandler, pinAuthenticationRequestHandler)
        .setBrowserRegistrationRequestHandler(registrationRequestHandler)
        .setMobileAuthWithPushRequestHandler(new MobileAuthWithPushRequestHandler(applicationContext))
        .setMobileAuthWithPushPinRequestHandler(new MobileAuthWithPushPinRequestHandler(applicationContext))
        .setMobileAuthWithPushFingerprintRequestHandler(new MobileAuthWithPushFingerprintRequestHandler(applicationContext))
        .setFingerprintAuthenticationRequestHandler(new FingerprintAuthenticationRequestHandler(applicationContext))
        .build();

OneginiFingerprintAuthenticationRequestHandler interface exposes four methods you should use to control the process of scanning the fingerprint and informing the end user about the progress:

  • startAuthentication(final UserProfile userProfile, final OneginiFingerprintCallback callback) triggered when a new fingerprint authentication request is made, providing an UserProfile object and a fingerprint callback;
  • onNextAuthenticationAttempt() called when user provided incorrect fingerprint but still haven't reach the failed attempts limit,
  • onFingerprintCaptured() invoked when user scanned his fingerprint and the fingerprint validation is performed. That's a good moment to show an update on the UI informing user about received attempt,
  • finishAuthentication() triggered when fingerprint scanning finished either with success or an error.

OneginiMobileAuthWithPushFingerprintRequestHandler works in exactly the same manner with a single change in parameters of startAuthentication() method, where instead of the UserProfile you get the OneginiMobileAuthenticationRequest object containing information about the push request as well as UserProfile. You can read more about mobile fingerprint authentication in Mobile authentication topic guide.

Example code for OneginiFingerprintAuthenticationRequestHandler implementation

public class FingerprintAuthenticationRequestHandler implements OneginiFingerprintAuthenticationRequestHandler {

  public static OneginiFingerprintCallback fingerprintCallback;
  private final Context context;

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

  @Override
  public void startAuthentication(final UserProfile userProfile, final OneginiFingerprintCallback oneginiFingerprintCallback) {
    fingerprintCallback = oneginiFingerprintCallback;
    startFingerprintActivity(MSG_EXTRA_START);
  }

  @Override
  public void onNextAuthenticationAttempt() {
    startFingerprintActivity(MSG_EXTRA_RECEIVED_FINGERPRINT);
  }

  @Override
  public void onFingerprintCaptured() {
    startFingerprintActivity(MSG_EXTRA_SHOW_SCANNING);
  }

  @Override
  public void finishAuthentication() {
    startFingerprintActivity(MSG_EXTRA_CLOSE);
  }

  private void startFingerprintActivity(final String action) {
    final Intent intent = new Intent(context, FingerprintActivity.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
    intent.putExtra(FingerprintActivity.MSG_EXTRA_ACTION, action);
    context.startActivity(intent);
  }
}

To control the flow of fingerprint authentication you should use provided OneginiFingerprintCallback callback. It consists of three methods:

  • acceptAuthenticationRequest() that should be called when user accepts fingerprint authentication request,
  • denyAuthenticationRequest which should be triggered when user denies the fingerprint authentication request, which can be done by calling the OneginiFingerprintCallback#denyAuthenticationRequest method.
  • fallbackToPin that should be invoked when user decides to resign from fingerprint authentication and wants to enter his PIN to finish authentication.

In the example code above you should use the static instance of OneginiFingerprintCallback in the FingerprintActivity to react on user actions.