Authenticate user with FIDO

Introduction

The SDK allows you to authenticate users with authenticators that are compatible with FIDO (Fast Identity Online) specifications. During initialization the Onegini SDK performs a discovery of all FIDO authenticators that are installed in the device or in the application and are also enabled in the client configuration it the Token Server. Please note, that Onegini SDK doesn't provide any FIDO authenticators, but uses FIDO authenticators provided by the app or device developers. For example new Samsung's devices are usually shipped with a FIDO-compliant "Samsung fingerprint" authenticator that can be discovered and used by Onegini SDK.

Enabling FIDO authentication

In order to enable FIDO authentication for a user you need to request a list of not yet registered authenticators with UserClient#getNotRegisteredAuthenticators(final UserProfile userProfile). This method will return a set of OneginiAuthenticator that are possible to register for specified UserProfile. For an authenticated user you can register chosen authenticator providing the authenticator's instance to the 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.

Example code for registering a FIDO authenticator

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

// FIDO authentication is not always available
if (fidoAuthenticator == null) {
  return;
}

//to register the authenticator
OneginiSDK.getOneginiClient(context).getUserClient().registerAuthenticator(fidoAuthenticator, new OneginiAuthenticatorRegistrationHandler() {
    @Override
    public void onSuccess() {
      // 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.

Authentication handlers

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

Example code for supplying FIDO auth request handlers to the SDK

OneginiClientBuilder(applicationContext, createPinRequestHandler, pinAuthenticationRequestHandler)
        .setFidoAuthenticationRequestHandler(new FidoAuthenticationRequestHandler(applicationContext))
        .setFingerprintAuthenticatioRequestHandler(new FingerprintAuthenticationRequestHandler(applicationContext))
        .setMobileAuthWithPushRequestHandler(new MobileAuthWithPushRequestHandler(applicationContext))
        .setMobileAuthWithPushPinRequestHandler(new MobileAuthWithPushPinRequestHandler(applicationContext))
        .setMobileAuthWithPushFingerprintRequestHandler(new MobileAuthWithPushFingerprintRequestHandler(applicationContext))
        .setMobileAuthWithPushFidoRequestHandler(new MobileAuthWithPushFidoRequestHandler(applicationContext))
        .build();

OneginiFidoAuthenticationRequestHandler interface exposes two methods you should use to control the process of authentication:

  • startAuthentication(final UserProfile userProfile, final OneginiFidoCallback oneginiFidoCallback) triggered when a new FIDO authentication request is made, providing an UserProfile object and a FIDO callback;
  • finishAuthentication() triggered when FIDO authentication finished either with success or an error.

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

Example code for OneginiFidoAuthenticationRequestHandler implementation

public class FidoAuthenticationRequestHandler implements OneginiFidoAuthenticationRequestHandler {

  public static OneginiFidoCallback CALLBACK;

  private String userProfileId;

  private final Context context;

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

  @Override
  public void startAuthentication(final UserProfile userProfile, final OneginiFidoCallback oneginiFidoCallback) {
    CALLBACK = oneginiFidoCallback;
    userProfileId = userProfile.getProfileId();
    notifyActivity(COMMAND_START);
  }

  @Override
  public void finishAuthentication() {
    notifyActivity(COMMAND_FINISH);
  }

  private void notifyActivity(final String command) {
    final Intent intent = new Intent(context, FidoActivity.class);
    intent.putExtra(EXTRA_COMMAND, command);
    intent.putExtra(EXTRA_USER_PROFILE_ID, userProfileId);
    intent.addFlags(FLAG_ACTIVITY_NEW_TASK);
    context.startActivity(intent);
  }
}

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

  • acceptAuthenticationRequest() that should be called when user accepts to perform FIDO authentication attempt,
  • denyAuthenticationRequest which should be triggered when user denies the FIDO authentication request,
  • fallbackToPin that should be invoked when user decides to resign from FIDO authentication and wants to enter his PIN to finish authentication.

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