---
title: Create tree hooks
description: Use tree hooks to run custom server-side logic after an authentication tree successfully completes and creates a session. Tree hooks can perform post-authentication tasks, like setting persistent cookies, logging detailed audit events, or adding information to the final response that's sent to the client.
component: pingam
version: 8.1
page_id: pingam:am-authentication:post-authn-plugins-treehook
canonical_url: https://docs.pingidentity.com/pingam/8.1/am-authentication/post-authn-plugins-treehook.html
keywords: ["Authentication", "Nodes &amp; Trees", "Setup &amp; Configuration"]
page_aliases: ["authentication-guide:post-authn-plugins-treehook.adoc"]
section_ids:
  develop-tree-hooks-core: Core class of an authentication tree hook
  register-tree-hook: Register an authentication tree hook
---

# Create tree hooks

Use tree hooks to run custom server-side logic **after** an authentication tree successfully completes and creates a session. Tree hooks can perform post-authentication tasks, like setting persistent cookies, logging detailed audit events, or adding information to the final response that's sent to the client.

A hook isn't a standalone component. You register it from a specific authentication node during the authentication journey. When the tree finishes successfully, AM runs all registered hooks, which lets them act on the new session.

AM includes the following built-in authentication tree hooks:

| Tree hook                        | Used by node                                                                                                       | Details                                                                                                                                                                                                                                                                                                  |
| -------------------------------- | ------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `CreatePersistentCookieTreeHook` | [Set Persistent Cookie node](https://docs.pingidentity.com/auth-node-ref/8.1/set-persistent-cookie.html)           | Creates a JWT that contains session, encryption, and node details. The JWT is then used to set a persistent cookie on the response.                                                                                                                                                                      |
| `ErrorDetailsTreeHook`           | [Set Error Details node](https://docs.pingidentity.com/auth-node-ref/8.1/set-error-details.html)                   | Adds error details to the response when a tree ends in a failure state.To add error details to the message when the `acceptException()` method runs, inject the [TreeFailureResponse](../_attachments/apidocs/org/forgerock/openam/auth/node/api/TreeFailureResponse.html) object into your tree hook.   |
| `FailureDetailsTreeHook`         | [Set Failure Details node](https://docs.pingidentity.com/auth-node-ref/8.1/set-failure-details.html)               | Adds failure details to the response when a tree ends in a failure state.To add failure details to the message when the `acceptFailure()` method runs, inject the [TreeFailureResponse](../_attachments/apidocs/org/forgerock/openam/auth/node/api/TreeFailureResponse.html) object into your tree hook. |
| `SuccessDetailsTreeHook`         | [Set Success Details node](https://docs.pingidentity.com/auth-node-ref/8.1/set-success-details.html)               | Adds success details to the response.                                                                                                                                                                                                                                                                    |
| `UpdatePersistentCookieTreeHook` | [Persistent Cookie Decision node](https://docs.pingidentity.com/auth-node-ref/8.1/persistent-cookie-decision.html) | Recreates the specified persistent cookie with a new idle time and JWT `kid` header value.                                                                                                                                                                                                               |

## Core class of an authentication tree hook

This example shows an excerpt from the `UpdatePersistentCookieTreehook` class. The Persistent Cookie Decision node uses this tree hook to recreate and refresh a persistent cookie after a successful login.

```java
/**
 * 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;
        }
        // ... Logic to update and set cookie on response
    }
  //...
}
```

1 The `@TreeHook.Metadata` annotation registers the class as a Tree Hook and links it to a configuration class. In this case, it specifies that the hook uses the settings that you define for the `PersistentCookieDecisionNode`.

2 Your core class must implement the `TreeHook` interface, which makes sure it has methods like `accept()` that the authentication framework can call.

Learn more in the [TreeHook](../_attachments/apidocs/org/forgerock/openam/auth/node/api/TreeHook.html) interface in the *AM Public API Javadoc*.

3 AM uses the Google Guice framework for dependency injection.

The `@Inject` annotation on the constructor tells Guice to create a new instance of the hook and provide all required service objects and contextual parameters.

The `@Assisted` annotation is for parameters that are specific to the current authentication transaction:

* [Request](../_attachments/apidocs/org/forgerock/http/protocol/Request.html): The HTTP request that started the authentication journey.

* [Response](../_attachments/apidocs/org/forgerock/http/protocol/Response.html): The outgoing HTTP response that will be sent to the user agent. You can modify this response, for example, by adding cookies.

* `config`: The node configuration object. The type is defined by the `configClass` property in the `@TreeHook.Metadata` annotation.

* [Realm](../_attachments/apidocs/org/forgerock/openam/core/realms/Realm.html): The realm where authentication is taking place.

* [SSOToken](../_attachments/apidocs/com/iplanet/sso/SSOToken.html): The token that contains session details after a successful authentication.

* [TreeFailureResponse](../_attachments/apidocs/org/forgerock/openam/auth/node/api/TreeFailureResponse.html): An object that contains failure details for the `acceptFailure()` message and error details for the `acceptException()` message.

4 The `accept()` method contains the hook's core logic. The framework runs this method only after the authentication tree completes successfully.

You can optionally override the `acceptFailure()` or `acceptException()` methods to define what happens on failure or exception outcomes.

## Register an authentication tree hook

To register a tree hook, your node class must call the `addSessionHook()` method on an `ActionBuilder` instance.

For example, the `PersistentCookieDecisionNode` registers its hook like this:

```java
 @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());
    ...
```

You can specify a node version in the `addSessionHook()` method. This lets you associate different tree hooks with different node versions.

If you omit the version, it defaults to version 1 of the node.

Learn more about the `addSessionHook()` method in [ActionBuilder](../_attachments/apidocs/org/forgerock/openam/auth/node/api/Action.ActionBuilder.html).
