PingAM 8.0.0

Create tree hooks

This section explains how to create a hook used by a node within an authentication tree. These tree hooks can perform custom processing after an authentication tree has successfully completed and a session has been created.

AM includes the following authentication tree hooks:

Tree hook Used by node Details

CreatePersistentCookieTreeHook

Creates a JWT with the session, encryption, and node details. The JWT is then used to set a persistent cookie on the response.

ErrorDetailsTreeHook

Adds error details to the response.

You can inject a TreeFailureResponse object into your tree hook that adds error details to the message when the acceptException() method is run.

FailureDetailsTreeHook

Adds failure details to the response.

You can inject a TreeFailureResponse object into your tree hook that adds failure details to the message when the acceptFailure() method is run.

SuccessDetailsTreeHook

Adds success details to the response.

UpdatePersistentCookieTreeHook

Recreates the specified persistent cookie with new idle time and JWT kid header values.

The core class of an authentication tree hook

The following example shows an excerpt from the UpdatePersistentCookieTreehook class. The Persistent Cookie Decision node uses this tree hook to recreate the persistent cookie.

/**
 * A TreeHook for updating a persistent cookie.
 */
@TreeHook.Metadata(configClass = PersistentCookieDecisionNode.Config.class)  (1)
public class UpdatePersistentCookieTreeHook implements TreeHook {            (2)

    ...

    @Inject                                                                  (3)
    UpdatePersistentCookieTreeHook(@Assisted Request request,
            @Assisted Response response,
            @Assisted PersistentCookieDecisionNode.Config config,
            @Assisted Realm realm,
            PersistentJwtStringSupplier persistentJwtStringSupplier,
            PersistentCookieResponseHandler persistentCookieResponseHandler,
            SecretReferenceCache secretReferenceCache){
        this.request = request;
        this.response = response;
        this.config = config;
        this.persistentJwtStringSupplier = persistentJwtStringSupplier;
        this.persistentCookieResponseHandler = persistentCookieResponseHandler;
        this.secretCache = secretReferenceCache.realm(realm);
    }

    @Override
    public void accept() throws TreeHookException {                          (4)
        logger.debug("UpdatePersistentCookieTreeHook.accept");
        String orgName = PersistentCookieResponseHandler.getOrgName(response);
        Cookie originalJwt = getJwtCookie(request, config.persistentCookieName());

        if (originalJwt == null) {
            return;
        }
        ...
    }
  ...
}
1 The @TreeHook.Metadata annotation. Before defining the core class, use a Java @TreeHook.Metadata annotation to specify the class the tree hook uses for its configuration. Use the configClass property to specify the configuration class of the node that will be using the tree hook.

The node class must invoke ActionBuilder's addSessionHook method to specify the treehook class to be run after a successful login.

For example, in the PersistentCookieDecisionNode.class:

@Override
public Action process(TreeContext context) throws NodeProcessException {
    ...
    actionBuilder = actionBuilder
        .replaceSharedState(context.sharedState.copy().put(USERNAME, userName))
        .withUniversalId(identityService.getUniversalId(userName, realm, USER))
        .withIdentifiedIdentity(userName, USER)
        .putSessionProperty(generateSessionPropertyName(config.persistentCookieName()),
                config.persistentCookieName())
        .addSessionHook(UpdatePersistentCookieTreeHook.class, nodeId, getClass().getSimpleName());
    ...
}
2 The core class must implement the TreeHook interface.

Learn more in the TreeHook interface in the AM Public API Javadoc.

3 AM uses Google’s Guice dependency injection framework for authentication nodes and tree hooks. Use the @Inject annotation to construct a new instance of the tree hook, specifying the configuration interface set up earlier and any other required parameters.

You can use the @Assisted annotation to pass in the following parameters:

  • SSOToken: The token with details of the session, following a successful authentication.

  • Response: The response sent to the user on successful authentication.

  • Request: The authentication request.

  • Realm: The realm in which authentication is taking place.

  • config: The node configuration object. The type is defined by the @TreeHook.Metadata annotation.

  • TreeFailureResponse: An object that contains the failure details for the acceptFailure() message and the error details for the acceptException() message.

Learn more in the Inject annotation type and the Assisted annotation type in the Google Guice Javadoc.

4 Implement the public void accept() method to define actions to perform on a successful journey outcome.

Optionally, override the void acceptFailure() or void acceptException() methods to define actions to perform on failure or exceptions.

The main logic of a tree hook is handled by these two methods.