Ping SDKs

Ping (ForgeRock) Authenticator module

Ping (ForgeRock) Authenticator module

Server support:

  • PingOne

  • PingOne Advanced Identity Cloud

  • PingAM

  • PingFederate

SDK support:

  • Ping SDK for Android

  • Ping SDK for iOS

  • Ping SDK for JavaScript

The Ping (ForgeRock) Authenticator module helps you build the functionality of the ForgeRock Authenticator application into your own Android and iOS apps.

The module supports:

  • Time-based one-time passwords (TOTP)

  • HMAC-based one-time passwords (HOTP)

  • Push notifications

Getting started with the Ping (ForgeRock) Authenticator module

Refer to the following topics to set up and get started with the Ping (ForgeRock) Authenticator module in your Android and iOS app projects:

Set up your Ping (ForgeRock) Authenticator module project

Learn how to configure compile options, add module dependencies, and declare the permissions required to run the Ping (ForgeRock) Authenticator module in your Android and iOS apps.

Initialize the Ping (ForgeRock) Authenticator module

After setting up your project, find out how to start the Ping (ForgeRock) Authenticator module so you can begin implementing your MFA use cases.

Optional tasks

Customize the storage client

Optionally, implement and register your own StorageClient interface to override the default storage mechanisms.

For example, you could use an SQLite database or other storage destination.

Set up your Ping (ForgeRock) Authenticator module project

Android

Set compile options

The Ping SDK for Android requires at least Java 8 (v1.8). Configure the compile options in your project to use this version, or newer.

For example, to specify Java 17, in your build.gradle file, add the following code at the top level:

kotlin {
  jvmToolchain {
    languageVersion.set(JavaLanguageVersion.of(17))
  }
}
gradle

Add module dependencies

Add the following dependency to use the Ping (ForgeRock) Authenticator module in your Android applications:

dependencies {
    ...
    implementation 'org.forgerock:forgerock-authenticator:4.7.0'
}
gradle

Additional dependencies you may require:

Feature Dependency

Push notifications

com.google.firebase:firebase-messaging:20.2.0

Request notification permissions

To process push notifications successfully on Android 13 (API level 33) and later, the app must request the new Notification runtime permission for sending non-exempt notifications from an app.

Declare the permission

To request the new notification permission from your app, update your app to target Android 13 (API level 33) and declare POST_NOTIFICATIONS in your app’s manifest file, as in the following code snippet:

<manifest ...>
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
    <application ...>
        ...
    </application>
</manifest>
xml

iOS

Install the Ping (ForgeRock) Authenticator module using CocoaPods

CocoaPods is a dependency manager for iOS projects, and is a simple way to integrate the Ping (ForgeRock) Authenticator module into your application.

  1. If you do not already have CocoaPods, install the latest version.

  2. In a terminal window, run the following command to create a new Podfile:

    pod init
  3. Add the following lines to your Podfile:

    pod 'FRAuthenticator'
  4. Run the following command to install pods:

    pod install

Install the Ping (ForgeRock) Authenticator module using Swift Package Manager (SPM)

  1. With your project open in Xcode, select File > Add Package Dependencies.

  2. In the search bar, enter the Ping SDK for iOS repository URL: https://github.com/ForgeRock/forgerock-ios-sdk.

  3. Select the forgerock-ios-sdk package, and then click Add Package.

  4. In the Choose Package Products dialog, ensure that the FRAuthenticator library is added to your target project:

    spm select authenticator module
    Figure 1. Adding the 'FRAuthenticator' module to an iOS project.
  5. Click Add Package.

  6. In your project, import the module:

    // Import the Ping (ForgeRock) Authenticator module
    import FRAuthenticator
    swift

Initialize the Ping (ForgeRock) Authenticator module

Android

Start the module

To use the features of the Ping (ForgeRock) Authenticator module, add code similar to the following to your application:

FRAClient fraClient = new FRAClient.FRAClientBuilder()
    .withContext(this)
    .start();
java

iOS

Start the module

To use the features of the Ping (ForgeRock) Authenticator module in your iOS app, first import the FRAuthenticator:

import FRAuthenticator
swift

And secondly, add code similar to the following to your application:

FRAClient.start()
swift

Customize the storage client

The Ping (ForgeRock) Authenticator module lets you customize the storage client and manages all data through that client.

Android

The Ping (ForgeRock) Authenticator module offers a default storage client that uses SecuredSharedPreferences, an encrypted storage mechanism built on Android SharedPreferences. It is available in the forgerock-core module.

SecuredSharedPreferences stores and manages all shared secret account information and notifications.

The Authenticator module lets you customize the StorageClient. You can implement the StorageClient interface, and register your own StorageClient in the module.

You can implement it with SQLite EncryptedSharedPreferences, or any other storage destination.

The Ping (ForgeRock) Authenticator module uses your storage client and manages all data through that client.

To customize the StorageClient, implement the following interfaces:

public interface StorageClient {
    /**
     * Get the Account object with its id
     * @param accountId The account unique ID
     * @return The account object.
     */
    Account getAccount(String accountId);
    /**
     * Get all accounts stored in the system.
     * @return The complete list of accounts.
     */
    List<Account> getAllAccounts();
    /**
     * Delete the Account that was passed in.
     * @param account The account object to delete.
     * @return boolean as result of the operation
     */
    boolean removeAccount(Account account);
    /**
     * Add or Update the Account to the storage system.
     * @param account The Account to store or update.
     * @return boolean as result of the operation
     */
    boolean setAccount(Account account);
    /**
     * Get the mechanisms associated with an account.
     * @param account The Account object
     * @return The list of mechanisms for the account.
     */
    List<Mechanism> getMechanismsForAccount(Account account);
    /**
     * Get the mechanism by UUID.
     * @param mechanismUID The uniquely identifiable UUID for the mechanism
     * @return The mechanism object.
     */
    Mechanism getMechanismByUUID(String mechanismUID);
    /**
     * Delete the mechanism uniquely identified by an id.
     * @param mechanism The mechanism object to delete.
     * @return boolean as result of the operation
     */
    boolean removeMechanism(Mechanism mechanism);
    /**
     * Add or update the mechanism to the storage system.
     * If the owning Account is not yet stored, store that as well.
     * @param mechanism The mechanism to store or update.
     * @return boolean as result of the operation
     */
    boolean setMechanism(Mechanism mechanism);
    /**
     * Get all notifications for within the mechanism.
     * @param mechanism The mechanism object
     * @return The list of notifications for the mechanism.
     */
    List<PushNotification> getAllNotificationsForMechanism(Mechanism mechanism);
    /**
     * Delete the pushNotification uniquely identified by an id.
     * @param pushNotification The pushNotification object to delete.
     */
    boolean removeNotification(PushNotification pushNotification);
    /**
     * Add or update the pushNotification to the storage system.
     * @param pushNotification The pushNotification to store.
     * @return boolean as result of the operation
     */
    boolean setNotification(PushNotification pushNotification);
    /**
     * Whether the storage system currently contains any data.
     * @return True if the storage system is empty, false otherwise.
     */
    boolean isEmpty();
}
java

For each method of getting an Account, Mechanism, or PushNotification object, your StorageClient should only be responsible for retrieving the objects, and not any other object associated with it.

For example, when retrieving Account objects, the StorageClient should not be responsible for retrieving Mechanism and PushNotification objects. All object mapping and associations are handled by the Ping (ForgeRock) Authenticator module itself.

After implementing your custom StorageClient, register it to FRAClient as follows:

//Initiate your custom StorageClient
StorageClient customStorageClient = CustomStorageClient()

//Register it to FRAClient
FRAClient fraClient = new FRAClient.FRAClientBuilder()
                .withContext(this)
                .withStorage(customStorageClient)
                .start();
java

You must register the StorageClient before you start the Ping SDK.

Once the SDK starts, the StorageClient used by FRAClient cannot be changed.

iOS

The ForgeRock Authenticator default storage client utilizes both Apple’s Keychain Service, and Secure Enclave.

This means that the Ping (ForgeRock) Authenticator module safely stores all shared secrets, account information, and notifications.

You can also customize the StorageClient. You can implement the StorageClient protocol, and register your own StorageClient with the Ping (ForgeRock) Authenticator module.

For example, you could customize StorageClient to use SQLite, CoreData, or any other storage destination.

The Ping (ForgeRock) Authenticator module uses your storage client and manages all data through that client.

To customize StorageClient you must implement the following interfaces:

/// StorageClient protocol represents predefined interfaces and protocols for FRAuthenticator's storage method.
public protocol StorageClient {

    /// Stores Account object into Storage Client and returns discardable Boolean result of operation.
    /// - Parameter account: Account object to store.
    @discardableResult func setAccount(account: Account) -> Bool

    /// Removes Account object from Storage Client, and returns discardable Boolean result of operation.
    /// - Parameter account: Account object to remove.
    @discardableResult func removeAccount(account: Account) -> Bool

    /// Retrieves Account object with its unique identifier.
    /// - Parameter accountIdentifier: String value of Account's unique identifier.
    func getAccount(accountIdentifier: String) -> Account?

    /// Retrieves all Account objects stored in Storage Client.
    func getAllAccounts() -> [Account]

    /// Stores Mechanism object into Storage Client, and returns discardable Boolean result of operation.
    /// - Parameter mechanism: Mechanism object to store.
    @discardableResult func setMechanism(mechanism: Mechanism) -> Bool

    /// Removes Mechanism object from Storage Client, and returns discardable Boolean result of operation.
    /// - Parameter mechanism: Mechanism object to remove.
    @discardableResult func removeMechanism(mechanism: Mechanism) -> Bool

    /// Retrieves all Mechanism objects stored in Storage Client.
    /// - Parameter account: Account object that is associated with Mechanism(s).
    func getMechanismsForAccount(account: Account) -> [Mechanism]

    /// Retrieves Mechanism object with given Mechanism UUID.
    /// - Parameter uuid: UUID of Mechanism.
    func getMechanismForUUID(uuid: String) -> Mechanism?

    /// Stores PushNotification object into Storage Client, and returns discardable Boolean result of operation.
    /// - Parameter notification: PushNotification object to store.
    @discardableResult func setNotification(notification: PushNotification) -> Bool

    /// Removes PushNotification object from Storage Client, and returns discardable Boolean result of operation.
    /// - Parameter notification: PushNotification object to remove.
    @discardableResult func removeNotification(notification: PushNotification) -> Bool

    /// Retrieves all Notification objects from Storage Client with given Mechanism object.
    /// - Parameter mechanism: Mechanism object that is associated with Notification(s).
    func getAllNotificationsForMechanism(mechanism: Mechanism) -> [PushNotification]

    /// Returns whether or not StorageClient has any data stored.
    @discardableResult func isEmpty() -> Bool
}
swift

For each method of getting an Account, Mechanism, or PushNotification object, your StorageClient should only be responsible for retrieving the objects, and not any other object associated with it.

For example, when retrieving Account objects, the StorageClient should not be responsible for retrieving Mechanism and PushNotification objects. All object mapping and associations are handled by the Ping (ForgeRock) Authenticator module itself.

After implementing your custom StorageClient, register it with your FRAClient as follows:

// Initiate your custom StorageClient
let customStorageClient = CustomStorageClient()
// Register it with your FRAClient
FRAClient.setStorage(storage: customStorageClient)
// Initiate the SDK
FRAClient.start()
swift

You must register the StorageClient before you start the Ping SDK.

Once the SDK starts, the StorageClient used by FRAClient cannot be changed.

Implement your use cases with the Ping (ForgeRock) Authenticator module

Find out how to integrate some common use case scenarios into your applications by using the Ping (ForgeRock) Authenticator module.

Mobile ForgeRock Authenticator

In this use case, you integrate the ability to authenticate a user with into your app.

To receive push notifications when authenticating, end users must register an Android or iOS device running your app built with the Ping (ForgeRock) Authenticator module.

Mobile Password Locked

In this use case you integrate the ability to generate a single-use, one-time password into your application by using the Ping (ForgeRock) Authenticator module.

The Ping (ForgeRock) Authenticator module supports time-based and HMAC-based one-time passwords.

Compliance Report

You can build and distribute your own authenticator app to your users so that they can participate in multi-factor authentication journeys, by using the Ping (ForgeRock) Authenticator module.

To help ensure the security of your app—​and therefore your system—​you can enable authenticator app policies.

Integrate MFA using push notifications

Applies to:

  • Ping SDK for Android

  • Ping SDK for iOS

  • Ping SDK for JavaScript

This use case explains how to integrate support for push authentication into your Android or iOS projects that use the Ping (ForgeRock) Authenticator module.

Tasks

Step 1. Configure Push notifications for Android

In this step, you configure Google Firebase Cloud Messaging (FCM), which handles sending the push notifications to Android devices.

You create a service account that provides access to the service for third-parties.

Step 2. Configure Push notifications for iOS

In this step, you configure Apple Push Notification service (APNS), which handles sending the push notifications to iOS devices.

You create a key that provides access to the service for third-parties.

Step 3. Configure Push notifications in AWS

In this step, you use the service account and key created in the previous steps to set up Amazon Simple Notification Service (SNS) to be able to route push notification messages to Android and iOS devices.

You also create a service account and associated access token to provide access to the service to your server.

Configure a server for push notifications

In this step, you configure your server to connect to SNS so that it can send out push notifications.

You also create an authentication journey that will register your client application as an MFA device, and send out push notifications.

Step 5: Configure the app for push notifications

In this step, you configure your application projects to use either Firebase Cloud Messaging or the Apple Push Notification service.

Step 6. Configure the Ping (ForgeRock) Authenticator module for push notifications

In this final step, you add the code to your application that obtains the unique device code required to ensure push notifications reach their intended audience.

You also add code that leverages the Ping (ForgeRock) Authenticator module to handle the push registration and authentication journey you created earlier.

Step 1. Configure Push notifications for Android

In this step, you configure Google Firebase Cloud Messaging (FCM), which handles sending the push notifications to Android devices.

You create service account that provides access to the service for third-parties.

Prerequisites

Create a project in Google Firebase

  1. Log in to the Google Firebase console.

  2. Click Add project.

  3. Enter a name for the project, for example sdk-authenticator-push, and then click Continue.

  4. Disable Google Analytics for the project, and then click Create project.

  5. When your Firebase project is ready, click Continue.

Add your Android app to the Firebase project

  1. Log in to the Google Firebase console.

  2. In the left menu, in Project Overview, click the gear icon () and then click Project settings.

    google firebase project settings en
    Figure 2. Opening the project settings panel in the Firebase console.
  3. In Your apps, click Add app.

  4. Click the Android icon ().

  5. In the Register app section:

    1. In Android package name, enter the package of the app into which you are integrating push notifications.

      For example, org.forgerock.authenticator.sample.

    2. In App nickname, enter a user-friendly name for the app.

      For example, Authenticator Push Sample.

    3. Click Register app.

  6. In the Download and then add config file section:

    1. Click Download google-services.json, and keep the file somewhere safe.

      You will need the file when configuring your application to access Firebase Cloud Messaging in a later step.

    2. Click Next.

  7. In the Add Firebase SDK section, click Next.

    You will add the Firebase SDKs to your application in a later step.

  8. In the Next steps section, click Continue to the console.

Create a key for the Firebase service account

  1. Log in to the Google Firebase console.

  2. In the left menu, in Project Overview, click the gear icon () and then click Project settings.

    google firebase project settings en
    Figure 3. Opening the project settings panel in the Firebase console.
  3. On the Cloud Messaging tab, click Manage service accounts.

    The link opens the Google Cloud IAM & Admin page, and displays the service accounts automatically generated when you created the Firebase project:

    google cloud firebase service account en
    Figure 4. Google Cloud console showing the generated Firebase service account.
  4. In the Actions column, click the vertical ellipsis icon ( ) next to the service account, and then click Manage keys.

  5. On the Keys page, click Add key, and then click Create new key.

  6. Select JSON, and then click Create.

    The page generates a key for the Firebase service account, and downloads the JSON file.

    You will upload this file when you configure Push notifications in AWS.

Step 2. Configure Push notifications for iOS

In this step, you configure Apple Push Notification service (APNS), which handles sending the push notifications to iOS devices.

You create a key that provides access to the service for third-parties.

Prerequisites

  • An Apple developer Admin account.

    Developer accounts cannot create the required keys.

  • An iOS application in XCode configured with the Push Notifications capability.

    You can add capabilities when creating an iOS app project, or add them to an existing project. Refer to Adding capabilities to your app in the Apple developer documentation.

    For development purposes, you can download the Ping (ForgeRock) Authenticator module sample app from GitHub.

Register a new key for APNs

  1. With an admin account, log in to the Apple Developer console.

  2. Navigate to Program resources > Certificates, IDs & Profiles > Keys.

  3. Next to the Keys label, click the Add icon ().

  4. Enter a Key Name.

    For example, APNs key for Push.

  5. Select Apple Push Notifications service (APNs).

  6. Click Continue.

  7. Check the details of the key, and then click Register.

  8. On the Download Your Key page:

    1. Make a note of the 10-character Key ID.

      For example, YCH15BO820.

    2. Click Download and keep a copy of the .p8 file safe.

      You cannot download or view the key again, so ensure you have a local copy.
  9. Click Done.

You will upload the .p8 file and use the key ID when you configure Push notifications in AWS.

Step 3. Configure Push notifications in AWS

In this step, you use the service account and key created in the previous steps to set up Amazon Simple Notification Service (SNS) to be able to route push notification messages to Android and iOS devices.

You also create a service account and associated access token to provide access to the service to your server.

Set up AWS for Android push notifications

  1. Log in to the AWS console: https://console.aws.amazon.com/console/home

  2. In the search bar, enter SNS, and then select Simple Notification Service from the list of results.

    Click the star icon () to pin the service to the toolbar in the AWS console.
  3. In the left menu, navigate to Mobile  Push notifications.

  4. In the Platform applications panel, click Create platform application.

  5. On the Create platform application page:

    1. In Application name, enter a name for the platform application.

      For example, Android_Push_Messaging.

    2. In Push notification platform, select Firebase Cloud Messaging (FCM).

      The page displays the Firebase Cloud Messaging Credentials section.

      1. In Authentication method, select Token.

        The page displays additional fields.

      2. In Service JSON, click Choose file, and navigate to the JSON file that you downloaded from Firebase when you created a Firebase key previously.

    3. Click Create platform application.

      The page creates the application and displays the details pane:

      amazon sns arn android en
      Figure 5. An Android platform application in AWS, showing the ARN.
  6. Make a note of the ARN value. You need this value when you Configure a server for push notifications.

Set up AWS for iOS push notifications

  1. Log in to the AWS console: https://console.aws.amazon.com/console/home

  2. In the search bar, enter SNS, and then select Simple Notification Service from the list of results.

    Click the star icon () to pin the service to the toolbar in the AWS console.
  3. In the left menu, navigate to Mobile  Push notifications.

  4. In the Platform applications panel, click Create platform application.

  5. On the Create platform application page:

    1. In Application name, enter a name for the platform application.

      For example, iOS_Push_Messaging.

    2. In Push notification platform, select Apple iOS/VoIP/MacOS.

      The page displays the Apple credentials section.

    3. In the Apple credentials section:

      1. In Push service, select iOS.

      2. In Authentication method, select Token.

        The page displays additional fields.

      3. In Signing key, click Choose file, and navigate to the .p8 file that you downloaded from Apple when you registered a new key for APNs.

        After selecting the file, the page populates the Signing key text field with the private key from the .p8 file.

      4. In Signing key ID, enter the 10-digit ID of the key you created when you registered a new key for APNs.

        For example, YUGX2BO820.

      5. In Team ID, enter the ID of your team in the Apple Developer Program.

        You can view your Team ID on the Membership details page in the Apple developer console.
      6. In Bundle ID, enter the bundle ID of the iOS application you are adding push notifications to.

        For example, com.forgerock.authenticator.sample.

    4. Click Create platform application.

      The page creates the application and displays the details pane:

      amazon sns arn ios en
      Figure 6. An iOS platform application in AWS, showing the ARN.
  6. Make a note of the ARN value. You need this value when you Configure a server for push notifications.

Create a service account with access to the ARN endpoints

  1. Log in to the AWS console: https://console.aws.amazon.com/console/home

  2. In the search bar, enter IAM, and then select IAM from the list of results.

    Click the star icon () to pin the service to the toolbar in the AWS console.
  3. In the left menu, navigate to Access management  Users.

  4. Click Create user.

  5. In User name, enter a name for the user account that the access key will represent.

    For example, sns_arn_user.

  6. Click Next.

  7. In Permissions options, select Attach policies directly.

    The page displays additional fields.

  8. In Permissions policies, in the search bar, enter SNSFull, and then select the checkbox next to AmazonSNSFullAccess.

    amazon sns arn user permissions en
    Figure 7. Adding the SNS permission policy to a user in AWS IAM.
  9. Click Next, review the details of the account, and then click Create user.

Create an access token for the service account

  1. Log in to the AWS console: https://console.aws.amazon.com/console/home

  2. In the search bar, enter IAM, and then select IAM from the list of results.

    Click the star icon () to pin the service to the toolbar in the AWS console.
  3. In the left menu, navigate to Access management  Users, and then click the service account you created previously.

  4. In the Summary pane, click Create access key.

  5. On the Access key best practices & alternatives page:

    1. In Use case, select Third-party service

    2. Under Confirmation, select the I understand the above recommendation and want to proceed to create an access key checkbox.

    3. Click Next.

  6. In Description tag value, enter the purpose of the access key.

    For example, server access to SNS ARN endpoints

  7. Click Create access key.

  8. Make a note of the provided values:

    1. Access Key ID.

      For example, AKIAXOSPRCH15LEES

    2. Secret access key.

      For example, 9eF7EcWMZzChI51BBHkLeElXk8R3XHv7/n7QSiwoUFJ

    Click Download .csv file to download a file containing the values for safe-keeping.
  9. Click Done.

Step 4. Configure an PingOne Advanced Identity Cloud or PingAM server for push notifications

In this step, you configure your server to connect to SNS so that it can send out push notifications.

You also create an authentication journey that will register your client application as an MFA device, and send out push notifications.

Add the Authenticator (Push) service

In this step you configure your server to operate with the Ping (ForgeRock) Authenticator module.

  1. Log in to the PingOne Advanced Identity Cloud admin UI as an administrator.

  2. In the left menu pane, select Native Consoles > Access Management.

    The realm overview for the Alpha realm displays.

  3. Select Services, and then click Add a Service.

  4. In Choose a service type, select ForgeRock Authenticator (Push) Service, and then click Create.

  5. Click Save Changes to accept the default settings.

Connect your server to Amazon SNS

In this step you configure your server with the settings it needs to be able to contact Amazon SNS to send push notifications to mobile devices.

  1. Log in to the PingOne Advanced Identity Cloud admin UI as an administrator.

  2. In the left menu pane, select Native Consoles > Access Management.

    The realm overview for the Alpha realm displays.

  3. Select Services, and then click Add a Service.

  4. In Choose a service type, select Push Notification Service.

  5. In SNS Access Key ID, enter the Access key ID value of the access token you created previously.

    For example, AKIAXOSPRCH15LEES.

    If you downloaded the CSV file when you created the access key, the first value in the file is the Access Key ID.
  6. In SNS Access Key Secret, enter the Access key value from the access token you created previously.

    For example, 9eF7EcWMZzChI51BBHkLeElXk8R3XHv7/n7QSiwoUFJ.

    If you downloaded the CSV file when you created the access key, the second value in the CSV file is the Secret access key.
  7. In SNS Endpoint for APNS, enter the iOS ARN endpoint generated by Amazon SNS.

    For example, arn:aws:sns:eu-west-1:123412341234:app/APNS/iOS_Push_Messaging.

  8. In SNS Endpoint for GCM, enter the Android ARN endpoint generated by Amazon SNS.

    For example, arn:aws:sns:eu-west-1:123412341234:app/GCM/Android_Push_Messaging.

  9. Click Create, and then click Save Changes.

Create a push registration and authentication journey

In this step you create an authentication journey that registers a device running an app built with the Ping (ForgeRock) Authenticator module to the user’s profile if they have not done so already, then send a push notification to that device.

The journey then polls until it receives a response or timeout from the device. It verifies the returned data and completes the authentication journey if valid.

Choose whether you are creating the journey in PingOne Advanced Identity Cloud or a self-managed PingAM server, and follow the instructions to create the required authentication journey:

  1. In the PingOne Advanced Identity Cloud admin UI

    1. Select the realm that will contain the authentication journey.

    2. Select Journeys, and click New Journey.

    3. Enter a name for your tree in Name page; for example, MFAwithPush

    4. In Identity Object, select the identity type that will be authenticating, for example group Alpha realm - Users.

    5. Click Save.

      The authentication journey designer page is displayed with the default Start, Failure, and Success nodes.

  2. Add the following nodes to the designer area:

  3. Connect the nodes as shown:

    Connect the nodes to identify the user, send a push notification, and very the result.
    Figure 8. Connect the nodes to identify the user, send a push notification, and very the result.
  4. In the Push Sender node, select the type of push notification the journey sends to the ForgeRock Authenticator:

    Tap to Accept

    Requires the user to tap to accept.

    Display Challenge Code

    Requires the user to select one of three numbers displayed on their device. This selected number must match the code displayed in the browser for the request to be verified.

    Use Biometrics to Accept

    Requires the user’s biometric authentication to process the notification.

    For information on how these options appear in the ForgeRock Authenticator, refer to Authenticate using a push notification.

  5. Save your changes.

The tree you create is a simple example for the purposes of demonstrating a basic push authentication journey. In a production environment, you could include additional nodes, such as:

Get Authenticator App node

Provides links to download the ForgeRock Authenticator for Android and iOS.

MFA Registration Options node

Provides options for users to register a multi-factor authentication device, get the authenticator app, or skip the registration process.

Opt-out Multi-Factor Authentication node

Sets an attribute in the user’s profile which lets them skip multi-factor authentication.

Recovery Code Display node

Lets a user view recovery codes to use in case they lose or damage the authenticator device they register.

Recovery Code Collector Decision node

Lets a user enter their recovery codes to authenticate in case they have lost or damaged their registered authenticator device.

Retry Limit Decision node

Lets a journey loop a specified number of times, for example, in case the user’s device is experiencing connectivity issues, for example.

Step 5: Configure the app for push notifications

In this step, you configure your application projects to use either Firebase Cloud Messaging or the Apple Push Notification service.

Enabling push notification support in an Android app

  1. In Android Studio, open your authenticator app project and switch to the Project view.

  2. Copy the google-services.json file that you downloaded from the Firebase console into the app-level root directory of your authenticator app:

    anrdoid studio google services json en
    Figure 10. Adding the google-services.json to the app root in Android Studio.
  3. To make the file available to the app, add the Google services Gradle plugin (com.google.gms.google-services) as a dependency to your project.

    1. In your root-level Gradle file:

      build.gradle.kts
      plugins {
        id("io.github.gradle-nexus.publish-plugin") version "1.1.0"
        id("org.sonatype.gradle.plugins.scan") version "2.4.0"
        id("org.jetbrains.dokka") version "1.9.10"
        id("com.android.application") version "8.3.2" apply false
        id("com.android.library") version "8.3.2" apply false
        id("org.jetbrains.kotlin.android") version "1.9.22" apply false
        // ...
      
        // Add the dependency for the Google services Gradle plugin
        id("com.google.gms.google-services") version "4.4.2" apply false
      }
      kotlin
    2. In your app-level Gradle file:

      build.gradle.kts
      plugins {
        id("com.android.library")
        id("com.adarshr.test-logger")
        id("maven-publish")
        id("signing")
        id("kotlin-android")
        // ...
      
        // Add the Google services Gradle plugin
        id("com.google.gms.google-services")
      }
      kotlin
  4. Switch to the Android view in Android Studio, and add the following code to the authenticator application manifest file.

    Insert the code inside the <application> tag.

    AndroidManifest.xml
    <service
        android:name=".controller.FcmService"
        android:exported="false">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>
    xml

Enabling push notification support to an iOS app

  1. In Xcode, open your authenticator app project.

  2. In the left menu, select the project root folder.

  3. In the project pane, under Targets, click your application, then click the Signing & Capabilities tab.

  4. Confirm that the application has the Push Notifications capability:

    xcode push capability en
    Figure 11. Checking for the Push Notifications capability in Xcode.
  5. With an admin account, log in to the Apple Developer console.

  6. Navigate to Program resources > Certificates, IDs & Profiles > Identifiers.

  7. Click the name of the application to which you are adding push notification support.

  8. On the Capabilities tab, ensure Push Notifications is selected.

Step 6. Configure the Ping (ForgeRock) Authenticator module for push notifications

In this final step, you add the code to your application that obtains the unique device code required to ensure push notifications reach their intended audience.

You also add code that leverages the Ping (ForgeRock) Authenticator module to handle the push registration and authentication journey you created earlier.

Prerequisites

To complete the procedures on this page, you must set up your application to use the Ping (ForgeRock) Authenticator module:

Register a device token to receive notifications

The Ping (ForgeRock) Authenticator module uses an Apple or Google service to receive push notifications sent from your server via Amazon SNS.

Each instance of your application requires a unique device registration token to receive these push notifications.

Use the registerForRemoteNotifications() method to register the token:

// Retrieve the FCM token
FirebaseMessaging.getInstance().getToken()
        .addOnCompleteListener(task -> {
            if (!task.isSuccessful()) {
                Log.e(TAG, "getInstanceId failed", task.getException());
                return;
            }

            // Get new Instance ID token
            fcmToken = task.getResult();
            Log.v("FCM token:", fcmToken);

            // Register the token with the SDK to enable Push mechanisms
            try {
                fraClient.registerForRemoteNotifications(fcmToken);
            } catch (AuthenticatorException e) {
                Log.e(TAG,"Error registering FCM token: ", e);
            }
        });
java

Handle registration of the app for push notifications

The first time you authenticate to your authentication tree, you are asked to register a device by scanning a QR code.

Your application must implement a QR code scanning mechanism. The QR code contains the URI used for registering the device, although you could also offer a method for entering the URI manually.

After capturing the URI, register the authentication mechanism in your app:

fraClient.createMechanismFromUri("qrcode_scan_result", new FRAListener<Mechanism>() {

    @Override
    public void onSuccess(Mechanism mechanism) {
        // called when device enrollment was successful.
    }

    @Override
    public void onFailure(final MechanismCreationException e) {
        // called when device enrollment has failed.
    }
});
java

Handle push notifications from the server

Your app that uses the Ping (ForgeRock) Authenticator module needs to respond to incoming push notifications, and ask the user to either accept or reject the authentication.

Receive FCM Push notifications by using FirebaseMessagingService#onMessageReceived.

To handle RemoteMessage, use the FRAClient.handleMessage() method:

public void onMessageReceived(final RemoteMessage message) {
   PushNotification notification = fraClient.handleMessage(message);
}
java

Obtain values from the push notification payload

The pushNotification class provide the following methods for obtaining values from the payload received in the push notification:

Android method iOS method Description

getCustomPayload()

customPayload

Returns a JSON string containing the values specified in the Custom Payload Attributes property of the Push Sender node.

getMessage()

message

Returns the string specified in the User Message property of the Push Sender node, such as Login attempt from Demo at ForgeRock.

getContextInfo()

contextInfo

Returns a JSON string containing additional context information when the Share Context info property is enabled in the Push Sender node.

Possible attributes in the JSON string are as follows:

  • location

  • userAgent

  • remoteIp

Ensure you check these attributes for null values, as they depend on being able to be collected by the Device Profile Collector node.

Example:

{
  "location": {
    "latitude": 51.4517076,
    "longitude": -2.5950234
  },
  "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36",
  "remoteIp": "198.51.100.23"
}
json

getPushType()

pushType

Returns a PushType enum value that specifies the type of push notification to present to the user.

This value is based on the configuration of the Push Type property in the Push Sender node.

Possible values are:

PushType.default

Requires the user to tap to accept.

PushType.challenge

Requires the user to select one of three numbers displayed on their device.

This selected number must match the code displayed in the browser for the request to be verified.

PushType.biometric

Requires the user’s biometric authentication to process the notification.

getNumbersChallenge()

numbersChallengeArray

Returns an array of integers that matches those displayed on the login screen and populates the numbersChallenge attribute, if the Push Type property in the Push Sender node is set to Display Challenge Code.

timeAdded

timeAdded

Returns the timestamp of when the authentication server generated the push authentication payload.

Handle different push notification types

Use code similar to the following to determine which push type was requested in the payload:

if (notification.getPushType() == PushType.CHALLENGE) {
    notification.accept(choice, listener);
} else if (notification.getPushType() == PushType.BIOMETRIC) {
    notification.accept(null, null, true, activity, listener);
} else {
    notification.accept(listener);
}
java
Handle the default push type

The PushNotification class or object provides an accept method for handling a PushType.default authentication request:

pushNotification.accept(new FRAListener<Void>() {

    @Override
    public void onSuccess(Void result) {
        // called when accepting the push authentication request was successful.
    }

    @Override
    public void onFailure(final PushAuthenticationException e) {
        // called when denying the push authentication request, or it has failed.
    }
});
java
Handle the challenge push type

For PushType.challenge authentication requests, use the following accept method that receives the challenge as a parameter:

public final void accept(
    @NonNull String challengeResponse,
    @NonNull FRAListener<Void> listener
) {}
java
Handle the biometric push type

For PushType.biometric authentication requests, use the following accept method that processes the biometric authentication request:

@RequiresApi(Build.VERSION_CODES.M)
public final void accept(
    String title,
    String subtitle,
    boolean allowDeviceCredentials,
    @NonNull AppCompatActivity activity,
    @NonNull FRAListener<Void> listener
) {}
java

More information

Refer to the following links for information on some of the interfaces and objects used in this topic:

Android iOS

PushNotification

PushNotification

PushMechanism

PushMechanism

PushType

PushType

Integrate MFA using OATH one-time passwords

Applies to:

  • Ping SDK for Android

  • Ping SDK for iOS

  • Ping SDK for JavaScript

This topic explains how to integrate support for OATH one-time passwords into your projects that use the Ping (ForgeRock) Authenticator module.

Prerequisites

To integrate OATH one-time passwords into your application that uses the Ping (ForgeRock) Authenticator module, ensure you have completed the following tasks first:

  1. Configure your server to request a one-time password during the authentication journey.

  2. Integrate the Ping (ForgeRock) Authenticator module into your app.

  3. Start the Ping (ForgeRock) Authenticator module in your app.

Sample apps

You can find example source code for integrating one-time passwords in the sample authenticator application repositories on GitHub:

Step 1. Register your app

The first time you authenticate you are asked to register a device by scanning a QR code.

Your application must implement a QR code scanning mechanism. The QR code contains the URI used for registering the device, although you could also offer a method for entering the URI manually.

After obtaining the URI, register the authentication mechanism in your app:

Register the OATH mechanism by implementing the FRAClient.createMechanismFromUri() method, and use FRAListener to receive the newly created mechanism:

fraClient.createMechanismFromUri("qrcode_scan_result", new FRAListener<Mechanism>() {

    @Override
    public void onSuccess(Mechanism mechanism) {
        // called when device enrollment was successful.
    }

    @Override
    public void onFailure(final MechanismCreationException e) {
        // called when device enrollment has failed.
    }
});
java

Step 2. Generate one-time passwords

With the OATH mechanisms now registered, your app can obtain the current, and next tokens, as an OathTokenCode object:

OathTokenCode token = oath.getOathTokenCode();
String otp = token.getCurrentCode();
java

More information

Refer to the following links for information on some of the interfaces and objects used in this topic:

Android iOS

OathMechanism

OathMechanism

createMechanismFromUri

createMechanismFromUri

Integrate authenticator app policies

Applies to:

  • Ping SDK for Android

  • Ping SDK for iOS

  • Ping SDK for JavaScript

You can build and distribute your own authenticator app to your users so that they can participate in multi-factor authentication journeys. To help ensure the security of your app—​and therefore your system—​you can enable authenticator app policies.

This topic explains how to integrate support for authenticator app policies into your projects that use the Ping (ForgeRock) Authenticator module.

Prerequisites

To integrate app policies into your application that uses the Ping (ForgeRock) Authenticator module, ensure you have completed the following tasks first:

  1. Configure your server to apply app policies.

  2. Integrate the Ping (ForgeRock) Authenticator module into your app.

  3. Start the Ping (ForgeRock) Authenticator module in your app.

Step 1. Handle policies on the client

Policies are associated with an account registered in your authenticator app.

The Account class has the following attributes for handling app policies:

Attribute Type Visibility Description

lockingPolicy

String

Public

The policy that caused the account to become locked. Only the first policy that was breached is listed.

policies

String

Public

A JSON string containing the policy names to apply, as configured in the combined MFA node.

lock

Boolean

Private 1

Whether the account is currently locked or not.

1 Use the public isLocked method to determine whether the account is currently locked or not

You can use the lockAccount and unlockAccount methods to manage registered accounts. To lock an account, you need to provide the policy that has been breached, as follows:

// Reference to the authenticator object:
FRAClient fraClient = FRAClient.builder()
    .withContext(context)
    .start();

// Reference to the "Device tampering detection" policy:
FRAPolicy policy = new DeviceTamperingPolicy();

// Lock the account:
boolean result = fraClient.lockAccount(account, policy);
java

Step 2. Create custom policies

You can extend the new abstract class FRAPolicy to create new policies that you can attach to accounts.

In the class, implement the evaluate method which returns true when policy conditions are met or false if the conditions are breached. For example, if the tampered score exceeds the specified value, the evaluator would return false.

static class AppIsUpToDatePolicy extends FRAPolicy {
    @Override
    public String getName() {
        return "appIsUpToDate";
    }

    @Override
    public boolean evaluate(Context context) {
        // Policy condition logic here
        return true; // policy conditions met
        // return false; // policy conditions breached - lock account
    }
}
java

To have the SDK evaluate your new policy, create a policy evaluator, as follows:

Use FRAPolicyEvaluator.FRAPolicyEvaluatorBuilder and its methods withPolicies and withPolicy to pass policies to the evaluator:

FRAPolicyEvaluator policyEvaluator = new FRAPolicyEvaluator.FRAPolicyEvaluatorBuilder()
    .withPolicies(FRAPolicyEvaluator.DEFAULT_POLICIES)
    .withPolicy(new AppIsUpToDatePolicy())
    .build();
java
FRAPolicyEvaluator.DEFAULT_POLICIES includes both of the default built-in policies BiometricAvailablePolicy and DeviceTamperingPolicy.

Pass the policy evaluator when building your authenticator client:

FRAClient.builder()
    .withContext(context.getApplicationContext())
    .withPolicyEvaluator(policyEvaluator)
    .start();
java

If the policy evaluator fails, the SDK automatically locks the account.

Locked accounts block certain methods, including FRAClient.updateAccount, PushMechanism.accept and OATHMechanism.getNextOathToken. Calling these methods on a locked account throws an AccountLockException.

API reference

Browse API reference documentation for the Ping (ForgeRock) Authenticator module:


1. Use the combined MFA registration node if you intend to also add OATH one-time passwords as an MFA method.