Overview

The PingOne Mobile SDK provides the ability to integrate PingOne MFA functionality into your mobile applications.

The PingOne Mobile SDK API for Android is included in the SDK package. The functions, parameters and error codes are listed below.

The PingOne Mobile SDK package is available for download at https://github.com/pingidentity/pingone-mobile-sdk-android. Further details for setup and integrating PingOne Mobile SDK into your mobile apps are available in the README file in the Android folder of the downloadable package.

See Edit an application in the admin guide for the server-side configuration steps.

PingOne Mobile SDK sample app

The PingOne Mobile SDK bundle provides a sample app that includes all the basic flows in order to help you get started.

The sample app package for Android is available for download at https://github.com/pingidentity/pingone-mobile-sdk-android. Further details are available in the README file in the Android folder of the downloadable package.

Authenticator sample app

The Authenticator sample app is a mobile app that has the sole function of performing strong authentication. It provides a simple example for developers and solution architects, to enable easy and rapid deployment of an authenticator app with minimal effort.

For scenarios which solely require creation of a mobile authenticator rather than a full native mobile app, the Authenticator sample app offers a passwordless and secured solution, that only requires compilation of the sample with customer’s branding and credentials, and uploading it to the app store.

The Authenticator sample app package for Android is available for download at https://github.com/pingidentity/pingone-authenticator-sample-app-android/. Further details are available in the README file.

PingOne Mobile SDK API - Android

PingOne main public class

/**
 * Created by Ping Identity
 * Copyright © 2020 Ping Identity. All rights reserved.
 * Version 1.3.0
 *
 * Main public class that contains APIs
 */
@SuppressWarnings("unused")
@Keep
public class PingOne {

    private final static Logger logger = LoggerFactory.getLogger(PingOne.class);


    /**
     * Pairs the device with the PingOne server using the pairing key
     * @param context   application context
     * @param pairingKey    pairing key as a String
     * @param callback  {@link PingOneSDKCallback} notifies a completion
     **/
    @Deprecated
    public static void pair(Context context, String pairingKey, PingOneSDKCallback callback){
        logger.info("SDK called method=pair");
        PingOneInnerLogic innerLogic = new PingOneInnerLogic();
        innerLogic.executePairingRequest(context, pairingKey, callback);
    }

    /**
     * Pairs the device with the PingOne server using the pairing key
     * @param context   application context
     * @param pairingKey    pairing key as a String
     * @param callback  {@link PingOneSDKPairingCallback} notifies the status of the completion.
     * A wrapper method that contains Array List with authentication methods (One time passcode and Push) status.
     * Documentation for pairing objecterror codes:
     * https://apidocs.pingidentity.com/pingone/mobile-sdks/v1/api/#androidPairingObjectErrorCodes
     **/
    public static void pair(Context context, String pairingKey, PingOneSDKPairingCallback callback){
        logger.info("SDK called method=pair");
        PingOneInnerLogic innerLogic = new PingOneInnerLogic();
        innerLogic.executePairingRequest(context, pairingKey, callback);
    }


    /**
     * When using OpenID Connect, this is a mandatory post action method which should be
     * executed after receiving an id token from the PingOne SDK server.
     * @param idToken:  String
     * @param callback:  Will return PingOnePairingObjectCallback.
     * Will contain return PairingObject in case further action is required, such as approving the pairing
     * or error in case of failure.
     */
    public static void processIdToken(String idToken, PingOnePairingObjectCallback callback){
        logger.info("SDK called method=processIdToken");
        PingOneInnerLogic pingOneInnerLogic = new PingOneInnerLogic();
        pingOneInnerLogic.processAuthToken(idToken, callback);
    }


    /**
     * Set device remote notification token.
     * @param context an application context
     * @param fcmRegistrationIdToken the registration token retrieved from FCM
     * @param callback notifies a completion
     */
    public static void setDeviceToken(Context context, String fcmRegistrationIdToken, PingOneSDKCallback callback){
        logger.info("SDK called method=setDeviceToken");
        PingOneInnerLogic innerLogic = new PingOneInnerLogic();
        innerLogic.setDeviceToken(context, fcmRegistrationIdToken, callback);
    }

    /**
     * Process the remote notification received from PingOne
     * @param remoteMessage a remote message retrieved from FCM
     * @param callback PingOneNotificationCallback notifies about task completion. Will return
     * NotificationObject if process completed successfully or PingOneSDKError otherwise
     * @deprecated please use processRemoteNotification(Context context, RemoteMessage remoteMessage, PingOneNotificationCallback callback)
     * instead
     */
    @Deprecated
    public static void processRemoteNotification(RemoteMessage remoteMessage, PingOneNotificationCallback callback){
        logger.warn("SDK called deprecated method=processRemoteNotification");
        processRemoteNotification(null, remoteMessage, callback);
    }

    /**
     * Process the remote notification received from PingOne
     * @param remoteMessage a remote message retrieved from FCM
     * @param callback PingOneNotificationCallback notifies about task completion. Will return
     * NotificationObject if process completed successfully or PingOneSDKError otherwise
     */
    public static void processRemoteNotification(Context context, RemoteMessage remoteMessage, PingOneNotificationCallback callback){
        logger.info("SDK called method=processRemoteNotification");
        PingOneInnerLogic innerLogic = new PingOneInnerLogic();
        innerLogic.handlePush(context, remoteMessage, callback);
    }

    /**
     * Returns a payload string for any communication needed between the customer mobile app
     * and the PingOne SDK server.
     */
    public static String generateMobilePayload(Context context){
        logger.info("SDK called method=generateMobilePayload");
        PingOneInnerLogic innerLogic = new PingOneInnerLogic();
        return innerLogic.generateMobilePayload(context);
    }


    /**
     *  Returns all the paired users from the PingOne server.
     * @param context the context of calling application
     * @param callback a callback that will be triggered at completion
     */
    public static void getInfo(Context context, PingOneGetInfoCallback callback){
        logger.info("SDK called method=getInfo");
        PingOneInnerLogic innerLogic = new PingOneInnerLogic();
        innerLogic.getDeviceInfo(context, callback);
    }

    /**
     * Send logs to PingOne server.
     * @param context the context of calling application
     * @param callback a callback that will be triggered at completion
     */
    public static void sendLogs(Context context, PingOneSendLogsCallback callback){
        logger.info("SDK called method=sendLogs");
        PingOneInnerLogic innerLogic = new PingOneInnerLogic();
        innerLogic.sendLogs(context, callback);
    }

    /**
     * Requests the SDK to provide One Time Passcode
     * @param context the context of calling application
     * @param callback a callback that will be triggered at completion. Will contain the passcode data.
     */
    public static void getOneTimePassCode(Context context, PingOneOneTimePasscodeCallback callback){
        PingOneInnerLogic innerLogic = new PingOneInnerLogic();
        innerLogic.getOneTimePassCode(context, callback);
    }

    /**
     * Method that will notify the server not to send push messages to this device
     * @param context the context of calling application
     * @param allowPush a boolean that will tell the server to send push messages or not. Defaults to true.
     */
    public static void allowPushNotifications(Context context, boolean allowPush){
        logger.info("SDK called method=allowPushNotifications");
        PingOneInnerLogic innerLogic = new PingOneInnerLogic();
        innerLogic.allowPushNotifications(context, allowPush);
    }

    /**
     * Callback interface that will notify developers about asynchronous task completion
     * {@link PingOneSDKError} object will be null if process completed successfully
     */
    public interface PingOneSDKCallback {
        void onComplete(@Nullable PingOneSDKError error);
    }

    /**
     * Callback interface that will notify developers about asynchronous task completion
     * {@link PingOneSDKError} object will be null if process completed successfully
     * {@link PairingInfo} A wrapper method that contains Array List with authentication methods (One time passcode and Push) status.
     * will be null completed with error.
     */
    public interface PingOneSDKPairingCallback extends PingOneSDKCallback{
        void onComplete(PairingInfo pairingInfo, @Nullable PingOneSDKError error);
    }

    /**
     * Callback interface that will notify developers about processRemoteNotification task completion
     * {@link NotificationObject} will returned if process completed successfully
     * {@link PingOneSDKError} object will be null if process completed successfully
     */
    public interface PingOneNotificationCallback {
        void onComplete(@Nullable NotificationObject notificationObject, @Nullable PingOneSDKError error);
    }

    /**
     * Callback interface that will notify developers about processIdToken task completion
     * {@link PairingObject} will be returned if process completed successfully
     * {@link PingOneSDKError} object will be null if process completed successfully.
     * onComplete(null, null) will be triggered on OIDC login with already paired device
     */
    public interface PingOnePairingObjectCallback {
        void onComplete(@Nullable PairingObject pairingObject, @Nullable PingOneSDKError error);
    }

    /**
     * Callback interface that will notify developers about getInfo task completion
     * JsonObject containing array with all the paired users info will be returned
     * to the calling application on successful response.
     * {@link PingOneSDKError} object will be null if process completed successfully.
     */
    public interface PingOneGetInfoCallback {
        void onComplete(@Nullable JsonObject publicJson, @Nullable PingOneSDKError error);
    }

    /**
     * Callback interface that will notify developers about sendLogs task completion
     * String with unique support ID will be returned  in case the logs were sent successfully.
     * The supportId can then be passed to the Ping Identity support team for review.
     * {@link PingOneSDKError} object will be null if process completed successfully.
     */
    public interface PingOneSendLogsCallback {
        void onComplete(@Nullable String supportId, @Nullable PingOneSDKError error);
    }

    /**
     * Callback interface that will return One time passcode object.
     * {@link PingOneSDKError} object will be null if process completed successfully.
     * {@link OneTimePasscodeInfo} object will be null if process did not complete successfully.
     */
    public interface PingOneOneTimePasscodeCallback {
        void onComplete(@Nullable OneTimePasscodeInfo oneTimePasscodeInfo, @Nullable PingOneSDKError error);
    }

}

NotificationObject

/**
* Created by Ping Identity
* Copyright © 2020 Ping Identity. All rights reserved.
* Version 1.3.0
*
* NotificationObject represents an authentication request via remote notification.
* It can be approved or denied.
* Implements Parcelable so the developer will be able to pass it via intents in the application.
*/
public class NotificationObject implements Parcelable {
	
	/**
	* Approve authentication
	* @param context application context
	* @param callback a callback notifies a completion
	* Deprecated in version 1.1.0 please use approve(Context, String, PingOneSDKCallback) instead
	*/
	@Deprecated
	public void approve(Context context, final PingOneSDKCallback callback) ;

    /**
	* Approve authentication
	* @param context application context
	* @param authenticationMethod a String representing the authentication method that was used to 
	* authenticate the user on the authenticating device, for example, fpt (fingerprint), 
	* face (facial recognition) etc. Refer to the "amr" (Authentication Method Reference) 
	* values in https://tools.ietf.org/html/rfc8176/#section-2.
	* @param callback a callback notifies a completion
	*/
	public void approve(Context context, String authenticationMethod, final PingOne.PingOneSDKCallback callback);

	/**
	* Denies authentication
	* @param context application context
	* @param callback a callback notifies a completion
	*/
	public void deny(Context context, final PingOneSDKCallback callback);

	/**
     * The maximum time duration allowed from getting push till user response
     * @return int amount of seconds
     */
     public int getTimeoutDuration();

	/**
     * Returns client-context String object or null
     * if no context was passed by the server
     * @return client context as String
     */
    public String getClientContext();
}

PairingObject

/**
* Created by Ping Identity
* Copyright © 2020 Ping Identity. All rights reserved.
* Version 1.3.0
*
* an object returned if processIdToken flow proposes an automatic pairing
* to allow automatic pairing the developer should trigger the approve method of the object
*/
public class PairingObject implements Parcelable {
	
	/**
	* Approve pairing
	* @param context application context
	* @param callback a callback notifies a completion
	*/
	public void approve(Context context, final PingOneSDKCallback callback);
}

PingOneSDKError

/**
* Class that describes an error by error code and error message
*/
public class PingOneSDKError {
	public int getCode();
	public String getMessage();
}

Pairing object error codes

The pairing object always returns both a push authenticator status and an OTP status. If the status is FAILED, a Push authenticator error code and message or an OTP error code and message is returned with the status.

Push authenticator error codes

Error code Description
Any error string returned from FCM, for example Unregistered See more error codes and descriptions in Error codes for FCM failure conditions in the Firebase portal.
MissingPushCredentials There are no push credentials on the PingOne server.
MissingDeviceToken There is no device token on the PingOne server.
PushDisabled The push was disabled via the mobile SDK API.

OTP error codes

Error code Description
OneTimePasscodeRetriesExceeded On device pairing, the OTP can be verified within 3 attempts.
On checkOTP, the OTP can be verified within 3 attempts in every 15 minutes.
InvalidOneTimePasscode The user entered an invalid OTP.
OneTimePasscodeExpired On device pairing, the OTP can be verified within 15 minutes.
On checkOTP, there are no limitations except for OneTimePasscodeRetriesExceeded.
UnSynchronizedClock The mobile clock not synchronized with the generated secret.

PingOne Mobile SDK API error codes

Error Status Description
10000 INTERNAL_ERROR Internal Error
10001 DEVICE_TOKEN_IS_MISSING Device token was missing and is required to complete this action.
10002 UNRECOGNIZED_REMOTE_NOTIFICATION Remote notification isn’t from PingOne.
10003 SERVER_ERROR There was a server error.
10004 NO_CONNECTIVITY There was a problem with the network.
10005 PAIRING_KEY There was a problem with the pairing key.
10006 BUNDLE_ID There was a problem with the application ID.
10007 PAIRING_KEY_DATA_CENTER_MISMATCH Device may be paired in one regional data center only, and is already paired in another regional data center.
10008 DEVICE_IS_NOT_PAIRED Device is not paired.
10009 PUSH_CONFIRMATION_TIMEOUT Client confirmation delay responding to push notification, resulted in timeout.
10010 PASSCODE_NOT_VALID Client failed to verify due to invalid one time passcode sent to the server.