Orchestration SDK: Authenticator Activation on Android Studio

Hakim Aldaoub, March 17, 2021

The Orchestration SDK is an integral part of OneSpan Mobile Security Suite (MSS). It orchestrate the commands between the different components to ensure a successful activation on the integrated mobile application, enabling the security features of the Mobile Security Suite on the end-user mobile application. Today, we will explore the activation mechanism of an authenticator instance using the Orchestration SDK on a sample application.

Prerequisites:

The Activation Process

Activity Creation

The activation process starts upon the creation of an instance of the ActivationActivity class. The execution of the activity will lead to the startRegistration method to be attached to the onClick callback method as we see in the code snippet below. The method will then be waiting to be executed after the click event is triggered on the register button on the UI. 

// Register button

Button registerBtn = (Button) findViewById(R.id.btn_register);

registerBtn.setOnClickListener(new View.OnClickListener() {

    @Override
    public void onClick(View view) {

        // Make sure to hide keyboard
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
        startRegistration();
    }

}); 

Orchestrator builder and Client Device Data Collector (CDDC)

The orchestrationCallback object will be created with the current instance of the ActivationActivity. The instance will be passed to the orchestrationCallback as an argument referenced with the this keyword. Afterwards, an object of the inner Builder class of the Orchestrator class will be created. The purpose of the Builder object is to create an Orchestrator object following the concept of the Builder design pattern, as seen below.

private Orchestrator orchestrator;

orchestrationCallback = new SampleOrchestrationCallback(this);

    Orchestrator.Builder builder = new Orchestrator.Builder();

    orchestrator = builder

            .setDigipassSalt(Constants.SALT_DIGIPASS)

            .setStorageSalt(Constants.SALT_STORAGE)

            .setContext(getApplicationContext())

            .setDefaultDomain(Constants.DOMAIN)

            .setCDDCParams(CDDCUtils.getCDDCParams())

            .setErrorCallback(orchestrationCallback)

            .setWarningCallback(orchestrationCallback)

            .build();


    // Set values for the CDDC when available

    CDDCUtils.configure(orchestrator.getCDDCDataFeeder());

}

Before invoking the build method to complete the creation of the Orchestrator object, the following arguments should be defined as shown in the code above:

  • Hardcoded salts, which will be used for diversification with certain security features (e.g. device binding, secure storage). These salts will be derived by the Orchestration SDK Client to complicate reverse-engineering attacks.
  • Default domain: required if the Customer Application Server integrates OneSpan Authentication Server. If the Customer Mobile Application must manage multiple domains, the default domain can be dynamically overwritten for each action (e.g. startActivation).
  • A CDDCParams object, which will define the parameters for device data collection. These parameters are optional.
  • An OrchestrationErrorCallback object, in case of errors, it will be used to throw them from the Orchestration SDK Client to the Customer Mobile Application.
  • An OrchestrationWarningCallback object, in case of warnings, it will be used to throw them from the Orchestration SDK Client to the Customer Mobile Application.

After the Orchestrator object is built successfully, the static configure method of the CDDCUtils class will be called to set up the values for the CDDC data from the orchestrator.getCDDCDataFeeder().

Activation Parameters

The activation parameters will be configured inside the startRegistration method when it gets called. First, the current instance of the ActivationActivity will be set for the activationParams as an ActivationCallback, since it already implements it.

Also, the OrchestrationUser and the ActivationPassword are provided as activation parameters. They will be obtained from the UI Views after the end-user is prompted to provide them upon the first execution.

Finally, The Orchestrator object will set the UserAuthenticationCallback passing all the necessary arguments including the orchestrationCallback. Then it invokes the startActivation method, passing the activation parameters that have been configured earlier as shown below.


private void startRegistration() {

    // Get input strings

    userId = userIdView.getText().toString();

    String activationPassword = activationPasswordView.getText().toString();

    // Create activation configuration

    OnlineActivationParams activationParams = new OnlineActivationParams();

    activationParams.setActivationCallback(this);

    activationParams.setOrchestrationUser(new OrchestrationUser(userId));

    activationParams.setActivationPassword(activationPassword);
    // Used for custom password instead of default one

    orchestrator.setUserAuthenticationCallback(orchestrationCallback, 

    new UserAuthenticationCallback.UserAuthentication[]

    {UserAuthenticationCallback.UserAuthentication.PASSWORD});     
    // Show progress dialog & start activation

    progressDialog = UIUtils.displayProgress(this, getString(R.string.dialog_progress_activating));

    orchestrationCallback.setProgressDialog(progressDialog);

    orchestrator.startActivation(activationParams);

}

Since the ActivationActivity implements the OnlineActivationCallbackinterface, it should override all the declared callback methods inside it. The OnlineActivationCallback interface is used by the Orchestration SDK Client to interact with the Customer Mobile Application during the activation process. As seen in the sample code below, the following methods have been implemented for a successful activation and interaction with the integrated mobile app considering all the scenarios:

  • onActivationStepComplete: the method will be called upon each successful activation step. The commandSender will send the produced command each time to the server.
  • onActivationSuccess: The method will be called upon the success of the activation process.
  • onActivationInputError: The method will be called upon activation process error due to incorrect user input. The possible errors are listed in the OrchestrationErrorCodes class.
  • onActivationAborted: The method will be called upon the cancellation of the activation process.

Below are the definitions of the methods as appear in the sample app.

@Override
public void onActivationStepComplete(String command) {
     // Initialize custom async task for sending an orchestration command to the server
    CommandSender commandSender = new CommandSender(getApplicationContext(), new CommandSenderCallback() {

        @Override
        public void onCommandSendingFailure() {
            // Hide progress dialog and display error message

            UIUtils.hideProgress(progressDialog);

            UIUtils.displayAlert(ActivationActivity.this, getString(R.string.dialog_error_title), 
            getString(R.string.dialog_error_content_sending));

        }

        @Override
        public void onCommandSendingSuccess(String serverCommand) {

            // Handle server command

            orchestrator.execute(serverCommand);

        }

    });

    // Send command to server

    commandSender.execute(command);
}

@Override
public void onActivationSuccess() {

    // Hide progress
    UIUtils.hideProgress(progressDialog);

    // Store activated user identity in the local preferences
    SharedPreferencesStorage userStorage = new SharedPreferencesStorage(this);

    userStorage.setCurrentUser(userId);

    // Back to calling activity
    setResult(Activity.RESULT_OK);

    finish();
}

@Override
public void onActivationAborted() {

    // Hide progress
    UIUtils.hideProgress(progressDialog);

    // Display cancel message
    Log.d(TAG, "Activation cancelled by user");

    UIUtils.displayAlert(this, "Activation cancelled", "Activation cancelled by user");
}

@Override
public void onActivationInputError(OnlineActivationInputError error) {

    // Hide progress
    UIUtils.hideProgress(progressDialog);

    // User got it wrong, display specific error
    Log.e(TAG, "Exception in onActivationError", error.getActivationInputException());

    switch (error.getErrorCode()) {

        case OrchestrationErrorCodes.USER_ID_NULL_OR_EMPTY:
            userIdView.setError("User ID is null or empty");
            break;

        case OrchestrationErrorCodes.USER_ID_WRONG_FORMAT:
            userIdView.setError("User ID contains invalid characters");
            break;

        case OrchestrationErrorCodes.ACTIVATION_PASSWORD_NULL_OR_EMPTY:
            activationPasswordView.setError("The activation password is null or empty");
            break;

        case OrchestrationErrorCodes.ACTIVATION_PASSWORD_WRONG_LENGTH:
            activationPasswordView.setError("The activation password has a wrong length");
            break;

        case OrchestrationErrorCodes.ACTIVATION_PASSWORD_WRONG_CHECKSUM:
            activationPasswordView.setError("The activation password is invalid");
            break;

        default:
            UIUtils.displayAlert(this, "Error", "Unknown error");
            break;
    }
}

In the code block above, if the activation process encounters zero errors, the onActivationStepComplete method will get called multiple times, communicating the required commands to the server. Then it will hand the control to onActivationSuccess which in turn will finish the activation process and take the end-user the welcome page of the mobile application. Meanwhile, if an error occurred, the onActivationInputError will handle it. However if the activation was aborted for any reason, the onActivationAborted will take over and cancel the activation process in a proper way.

In this blog, we have highlighted the activation process of an authenticator through the integration of the Orchestration SDK. If you have any questions regarding this blog, feel free to reach us on the OneSpan Community Portal Forums.

OneSpan Developer: Intelligent Adaptive Authentication – Authenticator Assignment Endpoint

OneSpan Developer Community

Join the OneSpan Developer Community! Forums, blogs, documentation, SDK downloads, and more.

Join Today