PingAM 8.0.0

Include callbacks

Nodes use callbacks to enable interaction with the authenticating user.

You can’t create your own callbacks, but there are many existing implementations available to you. Learn more in Supported callbacks.

Calling the getCallbacks(Class<t> callbackType) method on a TreeContext, the sole argument to the process() method of a node, returns all callbacks of a particular type for the most recent request from the current node. For example, calling context.getCallbacks(PasswordCallback.class) returns a list of the PasswordCallback callbacks displayed in the UI most recently.

The following is an example of multiple callbacks created by a node and passed to the UI:

An example of multiple callbacks created by a node and passed to the UI.

To process the responses to callbacks, you must know the order of the callbacks in the list. You can find the position of the callbacks created by the current node by using the constant properties for each callback position in the processing node.

If the callbacks were created in previous nodes, their positions must be stored in the shared state before subsequent nodes can use them.

The following is the code that created the UI displayed in the previous image:

ImmutableList.of(
  new TextOutputCallback(messageType, message.toUpperCase()),
  new PasswordCallback(bundle.getString("oldPasswordCallback"), false),
  new PasswordCallback(bundle.getString("newPasswordCallback"), false),
  new PasswordCallback(bundle.getString("confirmPasswordCallback"), false),
  confirmationCallback
);

The order of callbacks defined in the code is preserved in the UI.

Send and execute JavaScript in a callback

A node can provide JavaScript for execution on the client-side browser.

For example, the following is a simple JavaScript script named hello-world.js:

alert("Hello, World!");

Execute the script on the client by using the following code:

String helloScript = getScriptAsString("hello-world.js");
ScriptTextOutputCallback scriptCallback = new ScriptTextOutputCallback(helloScript);
ImmutableList<Callback> callbacks = ImmutableList.of(scriptCallback);
return send(callbacks).build();

Variables can be injected using your favorite Java String utilities, such as String.format(script, myValue).

To retrieve the data back from the script, add HiddenValueCallback to the list of callbacks sent to the user, as follows:

HiddenValueCallback hiddenValueCallback = new HiddenValueCallback("myHiddenOutcome", "false");

The JavaScript needs to add the required data to the HiddenValueCallback and submit the form, for example:

document.getElementById('myHiddenOutcome').value = "client side data";
document.getElementById("loginButton_0").click();

In the process method of the node, retrieve the hidden callback as follows:

Optional<String> result = context.getCallback(HiddenValueCallback.class)
  .map(HiddenValueCallback::getValue)
  .filter(scriptOutput -> !Strings.isNullOrEmpty(scriptOutput));

if (result.isPresent()) {
  String myClientSideData = result.get();
}