PingAM 7.5.0

Node class

The Node class can access and modify the persisted state shared between the nodes within a tree, and can request input by using callbacks. The class also defines the possible exit paths from the node.

In Java terms, an authentication node is a class that implements the Node interface, org.forgerock.openam.auth.node.api.Node.

The SetSessionProperties class shows the steps to implement the Node interface:

package org.forgerock.openam.auth.nodes;

import java.util.Map;

import javax.inject.Inject;

import org.forgerock.openam.annotations.sm.Attribute;
import org.forgerock.openam.auth.node.api.Action;
import org.forgerock.openam.auth.node.api.Node;
import org.forgerock.openam.auth.node.api.SingleOutcomeNode;
import org.forgerock.openam.auth.node.api.TreeContext;
import org.forgerock.openam.auth.nodes.validators.SessionPropertyValidator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.inject.assistedinject.Assisted;

/*
 * A node that defines a configurable set of properties to add to
 * the user’s session if/when it is created.
 */
@Node.Metadata(outcomeProvider = SingleOutcomeNode.OutcomeProvider.class,
        configClass = SetSessionPropertiesNode.Config.class,
        tags = {"utilities"})                                           1
public class SetSessionPropertiesNode extends SingleOutcomeNode {       2

  /
   * Configuration for the node.
   /
  public interface Config {                                             3
    /
     * A map of property name to value.
     * @return a map of properties.
     /
    @Attribute(order = 100, validators = SessionPropertyValidator.class)
    Map<String, String> properties();
  }

  private final Config config;                                          4
  private final Logger logger = LoggerFactory.getLogger("SetSessionPropertiesNode.class");

  /
   * Constructs a new SetSessionPropertiesNode instance.
   * @param config Node configuration.
   */
  @Inject                                                               5
  public SetSessionPropertiesNode(@Assisted Config config) {
    this.config = config;
  }

  @Override
  public Action process(TreeContext context) {                          6
    logger.debug("SetSessionPropertiesNode started");
    Action.ActionBuilder actionBuilder = goToNext();
    config.properties().entrySet().forEach(property → {
      actionBuilder.putSessionProperty(property.getKey(), property.getValue());
      logger.debug("set session property {}", property);
    });
    return actionBuilder.build();
  }
}
Step Description Further information

1 Apply the @Node.Metadata annotation

The annotation specifies the outcome provider, configuration class, and optionally, the configuration validation class and tags.

Use an existing outcome provider such as SingleOutcomeNode.OutcomeProvider or AbstractDecisionNode.OutcomeProvider, or create a custom provider and reference the class from the annotation.

2 Implement the Node interface

Extend one of the following abstract classes to implement the Node interface:

SingleOutcomeNode

For nodes with a single exit path; for example Modify Auth Level node.

AbstractDecisionNode

For nodes with a boolean-type exit path (true/false, allow/deny); for example, Data Store Decision node.

Alternatively, write your own implementation of the Node interface to define custom exit paths.

Javadoc:

3 Implement the Config interface

The Config interface defines the configuration data for a node.

4 Define private constants and methods

Optional

5 Inject dependencies

Inject objects using Guice as this makes it easier to unit test your node.

This example specifies config as a parameter. You can also include supported AM classes, instances of third-party dependencies, or your own types.

6 Override the process method

The process method is where you store and retrieve state if required.

It takes a TreeContext parameter that you can use to access the request, callbacks, shared state and other input.

The method returns an Action object. This can be a response of callback to the user, an update of state, or a choice of outcome. The Action object encapsulates changes to state and flow control.

The choice of outcome in a simple decision node would be true or false, resulting in the authentication tree flow moving from the current node to a node at the relevant connection.