ForgeRock Developer Experience

Step 3. Develop the client app

Integrating your application with PingOne Protect enables you to perform risk evaluations during your customer’s journey.

Add code for the following tasks to fully integrate with PingOne Protect:

Initialize data collection

You must initialize the PingOne Signals SDK so that it collects the data needed to evaluate risk.

The earlier you can initialize the PingOne Signals SDK, the more data it can collect to make a risk evaluation.

You can initialize the PingOne Signals SDK by using the start() method, which supports the following parameters:

Parameter

Description

Android

iOS

JavaScript

envID

Required. Your PingOne environment identifier.

deviceAttributesToIgnore

Optional. A list of device attributes to ignore when collecting device signals.

isConsoleLogEnabled

consoleLogEnabled

When true, output SDK log messages in the developer console.

Default is false.

isLazyMetadata

lazyMetadata

When true, calculate metadata on demand rather than automatically after calling start.

Default is false.

isBehavioralDataCollection

behavioralDataCollection

When true, collect behavioral data.

Default is true.

N/A

hubUrl

Optional. The iframe URL to use for cross-storage device IDs.

There are two options for initializing the PingOne Signals SDK:

Initialize manually

Call the start() method before users start interacting with your application to gather the most data and make the most informed risk evaluations.

Pass in the configuration parameters as required.

  • Android

  • iOS

  • JavaScript

try {
  val params =
    PIInitParams(
      envId = "3072206d-c6ce-4c19-a366-f87e972c7cc3",
    )
  PIProtect.start(context, params)
  Logger.info("Settings Protect", "Initialize succeeded")
} catch (e: Exception) {
  Logger.error("Initialize Error", e.message)
  throw e
}
let initParams = PIInitParams(envId: "3072206d-c6ce-4c19-a366-f87e972c7cc3")
  PIProtect.start(initParams: initParams) { error in
    if let error = error as? NSError {
        FRLog.e("Initialize error: \(error.localizedDescription)")
    } else {
        FRLog.i("Initialize succeeded")
    }
  }
import { PIProtect } from '@forgerock/ping-protect';

try {
  // Initialize PingOne Protect with manual configuration
  PIProtect.start({ envId: '3072206d-c6ce-4c19-a366-f87e972c7cc3' });
} catch (err) {
  console.error(err);
}

Initialize based on a callback

Not all authentication journeys perform risk evaluations, and therefore do not need to initialize data collection. You can choose to initialize capture of data on receipt of the PingOneProtectInitializeCallback callback rather than during app start up.

The callback also provides the configuration parameters.

  • Android

  • iOS

  • JavaScript

try {
  val callback =
    node.getCallback(PingOneProtectInitializeCallback::class.java)
  callback.start(context)
} catch (e: PingOneProtectInitException) {
  Logger.error("PingOneInitException", e, e.message)
} catch (e: Exception) {
  Logger.error("PingOneInitException", e, e.message)
  callback.setClientError(e.message);
}
node.next()
if callback.type == "PingOneProtectInitializeCallback",
  let pingOneProtectInitCallback = callback as? PingOneProtectInitializeCallback
{
  pingOneProtectInitCallback.start { result in
    DispatchQueue.main.async {
      var initResult = ""
      switch result {
      case .success:
        initResult = "Success"
      case .failure(let error):
        initResult = "Error: \(error.localizedDescription)"
      }
      FRLog.i("PingOne Protect Initialize Result: \n\(initResult)")
      handleNode(node)
    }
  }
  return
}
import { PIProtect } from '@forgerock/ping-protect';

if (step.getCallbacksOfType('PingOneProtectInitializeCallback')) {
  const callback = step.getCallbackOfType('PingOneProtectInitializeCallback');

  // Obtain config properties from the callback
  const config = callback.getConfig();

  console.log(JSON.stringify(config));

  try {
    // Initialize PingOne Protect with configuration from callback
    await PIProtect.start(config);
  } catch (err) {
    // Add any errors to the callback
    callback.setClientError(err.message);
  }
}

FRAuth.next(step);

Pause and resume behavioral data capture

The SDKs provide the pauseBehavioralData() and resumeBehavioralData() methods for pausing and resuming the capture of behavioral data.

The PingOneProtectEvaluationCallback callback can include a flag to pause or resume behavioral capture that you should respond to as follows:

  • Android

  • iOS

  • JavaScript

val callback =
  node.getCallback(PingOneProtectEvaluationCallback::class.java)

const shouldPause = callback.pauseBehavioralData

Logger.info("PingOneProtectEvaluationCallback", "getPauseBehavioralData: ${shouldPause}")

if (shouldPause) {
  PIProtect.pauseBehavioralData()
}
if callback.type == "PingOneProtectEvaluationCallback",
  let pingOneProtectEvaluationCallback = callback as? PingOneProtectEvaluationCallback
{
  if let shouldPause = pingOneProtectEvaluationCallback.pauseBehavioralData, shouldPause {
    PIProtect.pauseBehavioralData()
  }
}
const callback = step.getCallbackOfType('PingOneProtectEvaluationCallback');
const shouldPause = callback.getPauseBehavioralData();

console.log(`getPauseBehavioralData: ${shouldPause}`);

if (shouldPause) {
  PIProtect.pauseBehavioralData();
}

Return collected data for a risk evaluation

To perform risk evaluations, the PingOne server requires the captured data.

On receipt of a PingOneProtectEvaluationCallback callback, use the getData() method to populate the response with the captured data.

  • Android

  • iOS

  • JavaScript

try {
  val callback =
    node.getCallback(PingOneProtectEvaluationCallback::class.java)
  callback.getData(context)
} catch (e: PingOneProtectEvaluationException) {
  Logger.error("PingOneRiskEvaluationCallback", e, e.message)
} catch (e: Exception) {
  Logger.error("PingOneRiskEvaluationCallback", e, e.message)
}
if callback.type == "PingOneProtectEvaluationCallback",
  let pingOneProtectEvaluationCallback = callback as? PingOneProtectEvaluationCallback
{
  pingOneProtectEvaluationCallback.getData { result in
    DispatchQueue.main.async {
      var evaluationResult = ""
      switch result {
      case .success:
        evaluationResult = "Success"
      case .failure(let error):
        evaluationResult = "Error: \(error.localizedDescription)"
      }
      FRLog.i("PingOne Protect Evaluation Result: \n\(evaluationResult)")
      handleNode(node)
    }
  }
  return
}
let data;

if (step.getCallbacksOfType('PingOneProtectEvaluationCallback')) {
  const callback = step.getCallbackOfType('PingOneProtectEvaluationCallback');
  try {
    // Asynchronous call
    data = await PIProtect.getData();
  } catch (err) {
    // Add any errors to the callback
    callback.setClientError(err.message);
  }
}
callback.setData(data);
FRAuth.next(step);
Copyright © 2010-2024 ForgeRock, all rights reserved.