Auth Request Management

Once the SDK is setup and the current device is linked, we can now manage Auth Requests. If you have not completed the basic integration steps found in the Authentication Management module, then please do so before continuing.

When an end-user is requesting authorization, use the AuthRequestManager to handle the operational flow.

A typical operational flow would be as follows:

  1. Check if there is a pending AuthRequest.
  2. Accept (or deny) the pending AuthRequest.
  3. Check and verify all AuthMethod factors required by the AuthRequestManager .
  4. Send back the response for the AuthRequest.
  5. Check the AuthRequestResponse to continue.

Note

If using a conditional geofence policy, the first call to retrieve the auth methods to verify will only contain the geofencing auth method. Make another call to retrieve the auth methods to verify after successfully verifying the geofence to retrieve the resulting policy’s required auth methods (if any).

For example:

private final AuthRequestResponseEvent authRequestResponseEvent = new AuthRequestResponseEvent() {
    @Override
    public void onSuccess(@NonNull AuthRequestResponse authRequestResponse) {
        final AuthRequestResponse.Result result = authRequestResponse.getResult();
        if (result == AuthRequestResponse.Result.APPROVED) {
            // auth request was successfully verified and approved
        } else if (result == AuthRequestResponse.Result.DENIED) {
            // auth request was was denied by the user
        } else {
            // auth request failed verification, check failure
            final Failure failure = authRequestResponse.getFailure();
        }
    }

    @Override
    public void onFailure(@NonNull Exception e) {
        // failed to get the response, check exception
    }
};

private final AuthRequestPushReceivedEvent authRequestPushReceivedEvent = new AuthRequestPushReceivedEvent() {
    @Override
    public void onSuccess(@Nullable Void aVoid) {
        // an auth request push event was received. calling checkForAuthRequest() should now give a valid pending auth request
        checkForPendingAuthRequest();
    }

    @Override
    public void onFailure(@NonNull Exception e) {
        // failed to get the auth request push event, check exception
    }
};

private final GetAuthRequestEventCallback getAuthRequestEventCallback = new GetAuthRequestEventCallback() {
    @Override
    public void onSuccess(@Nullable AuthRequest result) {
        if (result != null) {
            startAuthFlow(result);
        }
    }

    @Override
    public void onFailure(@NonNull Exception e) {
        // failed to get the auth request, check exception
    }
};

@Override
public void onResume() {
    super.onResume();
    authRequestManager.registerForEvents(authRequestPushReceivedEvent, authRequestResponseEvent);
}

@Override
public void onPause() {
    authRequestManager.registerForEvents(authRequestPushReceivedEvent, authRequestResponseEvent);
    super.onPause();
}

private void checkForPendingAuthRequest() {
    if (!AuthenticatorManager.instance.isDeviceLinked()) {
        return;
    }

    authRequestManager.checkForAuthRequest(getAuthRequestEventCallback);
}

private void startAuthFlow(AuthRequest authRequest) {
    // You may deny the auth request anytime by supplying a DenialReason to
    // authRequestManager.denyAndSend(authRequest, denialReasonObject);

    // accepting the request will automatically send the response if the conditions
    // for the policy were not met
    final boolean failedPolicy = authRequestManager.acceptAndSendIfFailed(authRequest);

    if (!failedPolicy) {
        // get the auth methods requiring verification for this auth request
        final List<Factor> methodsToVerify = authRequestManager.getAuthMethodsToVerify(authRequest);

        // verify the auth methods
        verifyMethods(methodsToVerify);
    }
}

private void verifyAuthMethods(List<AuthMethod> authMethodsToVerify) {
    for (AuthMethod authMethod : authMethodsToVerify) {
        verifyAuthMethod(authMethod);
    }
}

private void verifyAuthMethod(AuthMethod authMethod) {
    switch (authMethod) {
        case PIN_CODE:
            verifyPinCode();
            break;
        case CIRCLE_CODE:
            verifyCircleCode();
            break;
        case LOCATIONS:
            verifyLocations();
            break;
        case BIOMETRIC:
            verifyBiometric();
            break;
        case WEARABLES:
            verifyWearables();
            break;
        case GEOFENCING:
            verifyGeofence();
            break;
    }
}

private void verifyGeofence() {
    // verify that Manifest.permission.ACCESS_FINE_LOCATION is granted prior to this call
    GeofencesManager geofencesManager = AuthMethodManagerFactory.getGeofencesManager();
    geofencesManager.verifyGeofencesForAuthRequest(currentAuthRequest, new AuthMethodAuthRequestVerificationCallback() {
        @Override
        public void onVerificationSuccess(final boolean authRequestWasSent) {
            // To check if this was a conditional geofence, then make sure to call authRequestManager.getAuthMethodsToVerify(currentAuthRequest).
            // If this list is different, from the prior call to it, then it was a condition geofence.
        }

        @Override
        public void onVerificationFailure(final boolean authRequestWasSent,
                                   final @NonNull AuthMethodFailure failure,
                                   final boolean unlinkTriggered,
                                   final boolean unlinkWarningTriggered,
                                   final @Nullable Integer attemptsRemaining) {
            // failed to verify the remote geofence location, check failure
        }
    });
}

private void verifyPinCode(String pinCode) {
    PINCodeManager pinCodeManager = AuthMethodManagerFactory.getPINCodeManager();
    // retrieve pincode from user prior to this call
    pinCodeManager.verifyPINCodeForAuthRequest(pinCode, currentAuthRequest, new AuthMethodAuthRequestVerificationCallback() {
        @Override public void onVerificationSuccess(boolean b) {
            verifiedAuthMethod(AuthMethod.PIN_CODE);
        }

        @Override public void onVerificationFailure(boolean b, @NonNull AuthMethodFailure authMethodFailure, boolean b1, boolean b2, @Nullable Integer integer) {
            showToast("Failed to verify PIN Code. " + integer + " attempts remaining");
        }
    });
}

...

private void sendResponse(AuthRequest authRequest) {
    // once all factors are verified, send the response for the auth request
    authRequestManager.send(authRequest);
}

Additional Integration Information

AuthRequestManager

This manager is responsible for handling auth auth request and should be the entry point to your request flows.

public interface AuthRequestManager {
    // Use this variable to retrieve the NonNull TruValidate Multifactor Authentication implementation of this class, acts like a singleton for this interface.
    @NonNull AuthRequestManager instance = InternalAuthRequestManager.getInstance();

    // Use this method to check with the TruValidate Multifactor Authentication API if there is a pending {@link AuthRequest}
    // You can cancel this operation by calling Disposable.dispose()
    @NonNull Disposable check(final @Nullable GetAuthRequestEventCallback getAuthRequestEventCallback);

    // Use this method to accept the policy, whether immediate failure, pending AuthMethod approval,
    // or ready to send, with the corresponding AuthRequest
    // In the event that the user auto-failed the policy the response will be sent immediately, otherwise
    // implementors should continue forth by calling getAuthMethodsToVerify(AuthRequest) and verifying the AuthMethods
    // using the corresponding managers before calling send(AuthRequest).
    // Though this method is async, we do not allow cancelling the operation of sending the {@link AuthRequest}
    boolean accept(final @NonNull AuthRequest authRequest);

    // Use this method to send the response for an AuthRequest after it has been verified that
    // all AuthMethods retrievable via getAuthMethodsToVerify(AuthRequest) have been successfully verified
    // Though this method is async, we do not allow cancelling the operation of sending the AuthRequest
    // In the event that the user failed one of the AuthMethods while verifying do not call this method, the response
    // will have already been sent.
    void send(final @NonNull AuthRequest authRequest);

    // Use this method to deny and send the response for an {@link AuthRequest}
    // Though this method is async, we do not allow cancelling the operation of sending the {@link AuthRequest}
    void deny(final @NonNull AuthRequest authRequest, final @Nullable DenialReason denialReason) throws DenialReasonExpectedException;

    // Use this method after having called accept(AuthRequest) to get the AuthMethods that are
    // required to be verified by the user before sending the response for the provided AuthRequest
    @NonNull List<AuthMethod> getAuthMethodsToVerify(final @NonNull AuthRequest authRequest);

    // Register for events pertaining this manager class.
    // Permitted events are all those located within the com.launchkey.android.authenticator.sdk.core.auth_request_management.event_callback package
    void registerForEvents(final @NonNull Event... events);

    // Unregister for events pertaining this manager class.
    // Permitted events are all those located within the com.launchkey.android.authenticator.sdk.core.auth_request_management.event_callback package
    void unregisterForEvents(final @NonNull Event... events);
}

AuthRequest

An AuthRequest object is a data class holding all the information needed to display to an end-user about a request. An AuthRequest contains the following accessor methods:

public class AuthRequest {
    // return the unique identifier of an Auth Request.
    public @NonNull String getId();

    // return true if more details have been provided on the Auth Request, false otherwise.
    public boolean hasContext();

    // return details on the Auth Request.
    public @NonNull String getContext();

    // return title of the Auth Request.
    public @NonNull String getTitle();

    // return the timestamp in milliseconds at which point this Auth Request expires.
    public long getExpiresAtMillis();

    // return the timestamp in milliseconds at which point this Auth Request was created.
    public long getCreatedAtMillis();

    // return Service Profile model object representing the Service that initiated
    // this Auth Request. Currently only holds the Service's name.
    public @NonNull ServiceProfile getServiceProfile();

    // return Array of DenialReason model objects which currently only holds the
    // denial reason's id and message.
    public @NonNull DenialReason[] getDenialReasons();

    public AuthRequest createCopy();
}

Next Steps

You are now all setup with auth request management. It is recommended that you read Auth Request Management Events to handle all events regarding this module.

User Contributed

TransUnion links to user contributed code as a resource to its community. TransUnion does not in any way guarantee or warrant the quality and security of these code bases. User contributed code is supported by the creators. If you do find a link from the site to user contributed code that is malicious or inappropriate in any way, please report that link to TransUnion immediately and we will investigate the claim. Submit any issue to TransUnion support at https://transunion.com/support. ×