HYPR Passwordless

HYPR SDK for Android

🚧

Do This First

This article assumes you have already completed the HYPR SDK for Android Quick Start before continuing.

HYPR Passwordless provides the means to login to or unlock a paired machine.

🚧

Limited Functionality on MacOS

Currently, it is possible to log into, but it not possible to unlock, a macOS machine using HYPR.

SDK Interface

HYPR Passwordless uses the HyprApiActionAdapter and HyprDbAdapter SDK interfaces.

πŸ“˜

HYPR Code Objects

The following HYPR code objects are used in HYPR Passwordless mode:

  • HyprAppProfileData - Profile corresponding to a HYPR RP Application
  • HyprMachineProfileData - Profile corresponding to a machine (most likely a workstation or computer)
  • HyprMachineState - State of a machine
  • HyprOfflineData - Object containing the Offline State variables of a machine

πŸ“˜

DB IDs

Most HYPR code objects have a DB ID to uniquely identify it. The SDK interfaces often require a DB ID to indicate which object is being operated on at the time. HYPR Passwordless mode uses the following DB IDs:

  • App Profile DB ID
  • Machine Profile DB ID

HYPR Passwordless

This implementation involves using HYPR SDK for Android to authenticate into a workstation. This is a full HYPR implementation for direct communication with a HYPR RP Server / HYPR FIDO Server.

InterfaceHyprInit
HyprApiActionAdapter
HyprDbAdapter
Related ComponentsUIAdapter
User Agent
FIDO Client
ASMs
Authenticators
FunctionalityOOB Registration
Website Authentication
FIDO Operations

πŸ“˜

Learn More

To learn more about OOB Consumer Access and how to integrate it into your app, go to the Web Authentication page.

Database Setup

During the Quick Start you created a CustomHyprDbAdapter which extends the HyprDbAdapter class. HYPR Passwordless mode requires the following modifications to that custom class setup:

  • Set the HyprRpAppType to WorkstationOnly
  • Set your RP URL (BaseDomainUrl)
  • Set your RP Application ID (RpAppId)
// HYPR Passwordless Additions
appProfile.setHyprRpAppType(context, HyprRpAppType.WorkstationOnly);
appProfile.setBaseDomainUrl(context, "https://your-company-hypr-rp-address.com");
appProfile.setRpAppId(context, "your RP Application Id");

The complete class with those additions is shown here.

public class CustomHyprDbAdapter extends HyprDbAdapter {
    /**
     * Called after a new App Profile is created.
     * Put any DB customizations here for the new App Profile.
     *
     * @param context    current context
     * @param appProfile appProfile object that was just created
     */
    @Override
    public void onNewAppProfileCreated(@NonNull final Context context,
                                       @NonNull HyprAppProfileData appProfile) {
        // Workstation Access Additions
        appProfile.setHyprRpAppType(context, HyprRpAppType.WorkstationOnly);
        appProfile.setBaseDomainUrl(context, "https://your-company-hypr-rp-address.com");
        appProfile.setRpAppId(context, "your RP Application Id");

    }
}

Pair a Machine

Before a machine can be unlocked, it must be paired with a smart phone using one of the following methods:

  • Scan a QR code
  • Use an out-of-base PIN entry
  • Use a direct out-of-base PIN

πŸ“˜

Initiate Pairing Options

Three methods exist for launching an Activity to initiate pairing via the HyprApiActionAdapter:

  • QR Code: HyprApiActionAdapter.addMachineToAppProfileWithQrScanner()
  • PIN Entry: HyprApiActionAdapter.addMachineToAppProfileWithPinEntry()
  • PIN Direct: HyprApiActionAdapter.addMachineToAppProfileWithPinDirect()

The results are returned in onActivityResults with the resultCode of HYPR_OOB_DEVICE_SETUP_ACT_REQ_CODE.

  1. Using the example below, verify the HYPR Initialization is complete. If only using one App Profile, get the current Application Profile and the App Profile DB ID. See App Profiles for more details.

  2. Pass that App Profile DB ID into the addMachineToAppProfileWith method to start a HYPR SDK Activity which will perform the pairing.

  3. Results are returned in the onActivityResult method described in the HYPR Passwordless Activity Results section below. The result code is HYPR_OOB_DEVICE_SETUP_ACT_REQ_CODE.

void addMachineWithQrScanner(Activity activity) {
    if (App.isHyprInitComplete()) {
        try {
            HyprAppProfileData hyprAppProfileData = App.getHyprDbAdapter().getCurHyprAppProfileData(activity);
            HyprApiActionAdapter.addMachineToAppProfileWithQrScanner(activity, hyprAppProfileData.getDbId());
        } catch (HyprException exception) {
            exception.printStackTrace();
        }
    }
}

void addMachineWithHyprPinScreen(Activity activity) {
    if (App.isHyprInitComplete()) {
        try {
            HyprAppProfileData hyprAppProfileData = App.getHyprDbAdapter().getCurHyprAppProfileData(activity);
            HyprApiActionAdapter.addMachineToAppProfileWithPinEntry(activity, hyprAppProfileData.getDbId());
        } catch (HyprException exception) {
            exception.printStackTrace();
        }
    }
}

void addMachineWithDirectPin(Activity activity,
                                     String pin) {
    if (App.isHyprInitComplete()) {
        try {
            HyprAppProfileData hyprAppProfileData = App.getHyprDbAdapter().getCurHyprAppProfileData(activity);
            HyprApiActionAdapter.addMachineToAppProfileWithPinDirect(activity, hyprAppProfileData.getDbId(), pin);
        } catch (HyprException exception) {
            exception.printStackTrace();
        }
    }
}

Get Paired Machines

To perform an action with a paired machine, its Machine DB ID is required. This method will return the list of Machines.

πŸ“˜

Get Paired Machines Method

hyprAppProfileData.getHyprMachineProfileDatas() is used to get the list of HyprMachineProfileDatas.

This is a direct DB call and does not launch an Activity.

  1. Using the example below, verify the HYPR Initialization is complete. If only using one App Profile, get the current Application Profile and the App Profile DB ID. App Profiles has more details.

  2. From the App Profile, return the list of Machine Profiles with the getHyprMachineProfileDatas method.

The code sample below shows how to get a full list of paired machines and their DB IDs.

List<HyprMachineProfileData> getPairedMachines(Activity activity) {
    List<HyprMachineProfileData> list = new ArrayList<>();
    if (App.isHyprInitComplete()) {
        try {
            HyprAppProfileData hyprAppProfileData = App.getHyprDbAdapter().getCurHyprAppProfileData(activity);
            list = hyprAppProfileData.getHyprMachineProfileDatas();
        } catch (HyprException exception) {
            exception.printStackTrace();
        }
    }
    return list;
}

Update and Check Machine State

A machine can be in several states. An explanation of the possible statuses follows.

STATEDESCRIPTION
INITThis is the initial state. If a machine is in this state, it is not fully setup yet.
NO_STATUSThis is the state after a machine is fully registered, but before its state is checked.
INVALID_STATUSThere was an error checking the state.
UNLOCKEDThe machine is unlocked.
UNREACHABLEThe machine is not reachable, usually because it is not connected to the Internet.
LOCKEDThe machine is locked.

Depending on the state of the machine, it might not make sense to start certain actions. For example, if a computer is in the UNLOCKED state, then it makes no sense to unlock it.

πŸ“˜

Update Machine States Method

HyprApiActionAdapter.refreshWorkstationStatus() is used to launch an Activity to update the Machine States in the HYPR DB via the HyprApiActionAdapter:

The results are returned in onActivityResult with the resultCode of
HYPR_UPDATE_WORKSTATION_STATUS_ACT_REQ_CODE.

  1. Using the example below, verify the HYPR Initialization is complete. If only using one App Profile, get the current App Profile and the App Profile DB ID. App Profiles has more details.

  2. Pass that App Profile DB ID into the refreshWorkstationStatus method to start a HYPR SDK activity which will perform the call to the HYPR Server to get the Machine States and update those statuses automatically in the HYPR DB.

  3. The success/fail results are returned in the onActivityResult method described in the HYPR Passwordless Activity Results section. The result code is HYPR_UPDATE_WORKSTATION_STATUS_ACT_REQ_CODE.

  4. After this operation is complete and the results from onActivityResult are checked, obtain the current Machine State from the HYPR DB using the getPairedMachines method from the earlier section to get a list of Machine Profiles. Each Machine Profile will then contain the updated Machine State.

void updateMachineStates(Activity activity) {
    if (App.isHyprInitComplete()) {
        try {
            HyprAppProfileData hyprAppProfileData = App.getHyprDbAdapter().getCurHyprAppProfileData(activity);
            HyprApiActionAdapter.refreshWorkstationStatus(activity, hyprAppProfileData.getDbId());
        } catch (HyprException exception) {
            exception.printStackTrace();
        }
    }
}

void checkMachineStates(Activity activity) {
    if (App.isHyprInitComplete()) {
        List<HyprMachineProfileData> list = getPairedMachines(activity);
        for (HyprMachineProfileData machineProfileData : list) {
            String machineDbId = machineProfileData.getDbId();
            HyprMachineState machineState = machineProfileData.getMachineState();
            // update UI dependent on Machine State
        }
    }
}

Unlock a Machine

Machine Unlocks are done on a Machine Profile basis. Each Machine Profile has a DB ID that typically is passed into methods to tell the SDK which Machine Profile to use.

πŸ“˜

Unlock a Machine Method

HyprApiActionAdapter.unlockWorkstation() is used to launch an Activity to initiate a Machine Unlock via the HyprApiActionAdapter:

The results are returned in onActivityResults with the resultCode of
HYPR_LOGIN_ACT_UNLOCK_MACHINE_REQ_CODE.

  1. In the example below, check to make sure that the HYPR Initialization is complete. Passed into the method is the Machine DB ID. You should be keeping track of Machine Profile DB IDs for your UI elements that correlate with Machines.

  2. Pass that Machine Profile DB ID into the unlockWorkstation method to start a HYPR SDK activity which will perform the unlock.

  3. The results are returned in the onActivityResult method described in the HYPR Passwordless Activity Results section. The result code is HYPR_LOGIN_ACT_UNLOCK_MACHINE_REQ_CODE.

void unlockMachine(Activity activity,
                   String machineDbId) {
    if (App.isHyprInitComplete()) {
        HyprApiActionAdapter.unlockWorkstation(activity, machineDbId);
    }
}

Offline Unlock

If Offline Unlock is enabled in the HYPR Control Center, a user can complete an Offline Unlock to receive a PIN that can be used to unlock their computer. This can be done regardless of whether or not the smartphone and/or the computer have an Internet connection. The code sample below shows how to initiate an Offline Unlock and how to retrieve the offline PIN on a successful authentication.

πŸ“˜

Prerequisites

To initiate an Offline Unlock, the following must be true:

  • Offline Unlock is enabled (a check is done with the HYPR Control Center each time a standard online unlock is successfully completed)
  • At least one successful online unlock was completed (required because an authentication payload is needed to start an offline unlock)
  • There are unused offline PINs available

Offline Unlock is on a Machine Profile basis. Each Machine Profile has a DB ID that is passed to methods to tell the SDK which Machine Profile to use.

πŸ“˜

Offline Unlock

HyprApiActionAdapter.offlineUnlockWorkstation() is used to launch an Activity to initiate a Machine Offline Unlock via the HyprApiActionAdapter.

The results are returned in onActivityResults with the resultCode of
HYPR_LOGIN_ACT_UNLOCK_MACHINE_REQ_CODE.

  1. Using the example below, verify the HYPR Initialization is complete. Machine DB ID is passed to the method. Keep track of Machine Profile DB IDs for your UI elements that correlate with Machines.

  2. Check if the Offline Mode Unlock is available for use via the HyprOfflineData object. The Offline Data object can be retrieved from the Machine with getHyprOfflineData. From the Offline Data object, check to see that OfflineMode is enabled, that the Machine has performed a successful online unlock already, and that there are still Offline Tokens available for use.

  3. If those conditions are satisfied, pass that Machine Profile DB ID into the offlineUnlockWorkstation method to start a HYPR SDK activity which will perform the Offline Unlock PIN Retrieval.

  4. The results are returned in the onActivityResult method. The result code is HYPR_LOGIN_ACT_UNLOCK_MACHINE_REQ_CODE.

The PIN is contained in the onActivityResult intent data, in the HyprStatusResult object, the getSuccessPayload() method. PIN Retrieval from the data object is described in the HYPR Passwordless Activity Results section.

void offlineUnlock(Activity activity,
                   String machineDbId) {
    if (App.isHyprInitComplete()) {
        if (isOfflineModeAvailableAndReadyToUse(activity, machineDbId)) {
            HyprApiActionAdapter.offlineUnlockWorkstation(activity, machineDbId);
        }
    }
}

boolean isOfflineModeAvailableAndReadyToUse(Activity activity,
                                            String machineDbId) {
    try {
        HyprOfflineData offlineData = App.getHyprDbAdapter().getMachineProfileByDbId(activity, machineDbId).getHyprOfflineData();

        boolean isOfflineEnabled = offlineData.isOfflineEnabledAndSetup();
        boolean hasPerformedOnlineUnlockWithOfflineEnabled = offlineData.hasPerformedOnlineUnlockWithOfflineEnabled();
        boolean isTokensRemaining = offlineData.getTokenCountRemaining() > 0;

        return isOfflineEnabled && hasPerformedOnlineUnlockWithOfflineEnabled && isTokensRemaining;

    } catch (HyprException exception) {
        exception.printStackTrace();
        return false;
    }
}

Unpair a Machine

Unpairing a Machine is done on a Machine Profile basis. Each Machine Profile has a DB ID that is passed to methods to tell the SDK which Machine Profile to use.

πŸ“˜

Unpair a Computer Method

HyprApiActionAdapter.deleteWorkstation() is used to launch an Activity to initiate a Machine Unpair via the HyprApiActionAdapter.

The results are returned in onActivityResults with the resultCode of HYPR_DELETE_WORKSTATION_ACT_REQ_CODE.

  1. Using the example below, check to make sure that the HYPR Initialization is complete. Passed into the method is the Machine DB ID. Keep track of Machine Profile DB IDs for your UI elements that correlate with Machines.

  2. Pass that Machine Profile DB ID into the deleteWorkstation method to start a HYPR SDK activity which will perform the unpair.

  3. The results are returned in the onActivityResult method described in the HYPR Passwordless Activity Results section further below. The result code is HYPR_DELETE_WORKSTATION_ACT_REQ_CODE.

void unpairMachine(Activity activity,
                   String machineDbId) {
    if (App.isHyprInitComplete()) {
        HyprApiActionAdapter.deleteWorkstation(activity, machineDbId);
    }
}

HYPR Passwordless Activity Results

Results from all HyprApiActionAdapter operations are returned in the onActivityResults method. The standard result code returned for a successful HYPR SDK for Android Operation activity result is HYPR_ACT_RES_CODE_SUCCESS.

@Override
protected void onActivityResult(int requestCode,
                                int resultCode,
                                Intent data) {
    if (resultCode == HYPR_ACT_RES_CODE_SUCCESS) {
        handleSuccess(requestCode, data);

    } else {
        handleFailure(requestCode);
    }
}

void handleSuccess(int requestCode,
                   Intent data) {
    switch (requestCode) {
        case HYPR_OOB_DEVICE_SETUP_ACT_REQ_CODE:
            Toast.makeText(this, "Pairing Successful", Toast.LENGTH_SHORT).show();
            break;

        case HYPR_UPDATE_WORKSTATION_STATUS_ACT_REQ_CODE:
            Toast.makeText(this, "Update Status Successful", Toast.LENGTH_SHORT).show();
            break;
            
        case HYPR_LOGIN_ACT_UNLOCK_MACHINE_REQ_CODE:
            String pinText = "";
            if (data != null && data.hasExtra(INTENT_KEY_HYPR_STATUS_RESULT)) {
                HyprStatusResult hyprStatusResult = (HyprStatusResult) data.getSerializableExtra(INTENT_KEY_HYPR_STATUS_RESULT);
                if (hyprStatusResult != null) {
                    pinText = hyprStatusResult.getSuccessPayload();
                }
            }

            if (!TextUtils.isEmpty(pinText)) {
                // Offline login was performed. Offline PIN retrieved and can be displayed by the UI.
                Toast.makeText(this, "Offline Unlock PIN Retrieval Successful", Toast.LENGTH_SHORT).show();
            } else {
                // Standard login was performed. Handle standard login success here.
                Toast.makeText(this, "Unlock Machine Successful", Toast.LENGTH_SHORT).show();
            }
            break;

        case HYPR_DELETE_WORKSTATION_ACT_REQ_CODE:
            Toast.makeText(this, "Delete Machine Successful", Toast.LENGTH_SHORT).show();
            break;

        default:
            Toast.makeText(this, "Unknown Success", Toast.LENGTH_SHORT).show();
    }
}

void handleFailure(int requestCode) {
    switch (requestCode) {
        case HYPR_OOB_DEVICE_SETUP_ACT_REQ_CODE:
            Toast.makeText(this, "QR Pairing Failed", Toast.LENGTH_SHORT).show();
            break;

        case HYPR_UPDATE_WORKSTATION_STATUS_ACT_REQ_CODE:
            Toast.makeText(this, "Update Status Failed", Toast.LENGTH_SHORT).show();
            break;

        case HYPR_LOGIN_ACT_UNLOCK_MACHINE_REQ_CODE:
            Toast.makeText(this, "Unlock Machine Failed", Toast.LENGTH_SHORT).show();
            break;

        case HYPR_DELETE_WORKSTATION_ACT_REQ_CODE:
            Toast.makeText(this, "Delete Machine Failed", Toast.LENGTH_SHORT).show();
            break;

        default:
            Toast.makeText(this, "Unknown Failure", Toast.LENGTH_SHORT).show();
    }
}