Java Agents 2024.9

Implement a custom task handler

This section describes how to add a custom task handler to the list of handlers, and provides example handlers. At startup, Java Agent tries to instantiate the specified service resolver class. If unsuccessful, it instantiates the original service resolver.

  1. Place com.sun.identity.agents.arch.ServiceResolver on the classpath.

  2. Add com.sun.identity.agents.arch.ServiceResolver to the bootstrap property Service Resolver Class Name.

Use the following functions to return a list of class names to customize the task handler:

Function When to execute the class What the class must implement

List<String> getPreInboundTaskHandlers()

Before all other inbound task handlers

IAmFilterTaskHandler

List<String> getPostInboundTaskHandlers()

After all other inbound task handlers

IAmFilterTaskHandler

List<String> getPreSelfRedirectHandlers()

Before all other self-redirect task handlers

IAmFilterTaskHandler

List<String> getPostSelfRedirectHandlers()

After all other self-redirect task handlers

IAmFilterTaskHandler

List<String> getPreFilterResultHandlers()

Before all other result handlers

IAmFilterResultHandler

List<String> getPostFilterResultHandlers()

After all other result handlers

IAmFilterResultHandler.

If the named handler classes are not on the classpath, or do not implement the required interface, then:

  • Handler instantiation fails.

  • A message is logged at ERROR level.

  • The agent abandons processing and returns an HTTP 500, effectively denying all requests.

When a handler list is built, make sure that any isActive function implemented by your custom handler returns true, if appropriate. Any handler returning false is evicted.

For each InboundTaskHandler and SelfRedirectHandler, the process function is invoked until a non-null value, such as continue or block, is returned. The non-null value becomes the result for that resource access. Returning a null value indicates to carry on to the other handlers.

For FilterResultHandlers, returning a null value causes an error.

Example custom filter result task handler

/*
 * Copyright © 2019 - 2024 Ping Identity Corporation
 * This code is to be used exclusively in connection with Ping Identity Corporation
 *  software or services.
 * Ping Identity Corporation only offers such software or services to legal entities
* who have entered into a binding license agreement with Ping Identity Corporation.
*/
package com.sun.identity.agents.custom;

import static org.forgerock.agents.debug.AgentDebug.logTrace;

import javax.servlet.http.HttpServletRequest;

import org.forgerock.agents.util.Utils;

import com.sun.identity.agents.arch.AgentConfiguration;
import com.sun.identity.agents.arch.Manager;
import com.sun.identity.agents.filter.AmFilterMode;
import com.sun.identity.agents.filter.AmFilterRequestContext;
import com.sun.identity.agents.filter.AmFilterResult;
import com.sun.identity.agents.filter.AmFilterResultHandler;

/**
 * This is an example of a custom filter result task handler
 */
@SuppressWarnings("unused")
public class CustomFilterResultTaskHandler extends AmFilterResultHandler {

    public CustomFilterResultTaskHandler(Manager manager) {
        super(manager);
    }

    @Override
    public boolean isActive() {
        return true;
    }

    @Override
    public String getHandlerName() {
        return "CustomFilterResultTaskHandler";
    }

    @Override
    public AmFilterResult process(AmFilterRequestContext context, AmFilterResult result) {

        String applicationName = Utils.getApplicationName(context);
        AmFilterMode amFilterMode = AgentConfiguration.getTheFilterMode(applicationName);
        HttpServletRequest request = context.getHttpServletRequest();

        logTrace("Hello from {}, application name {}, filter mode {}, {} {}, result {}",
                getHandlerName(), applicationName, amFilterMode,
                request.getMethod(), request.getRequestURI(),
                result.toString());


        // Must return the result parameter, unless you have a really good reason not to.
        return result;
    }
}

Example custom self-redirect task handler

/*
 * Copyright © 2019 - 2024 Ping Identity Corporation
 * This code is to be used exclusively in connection with Ping Identity Corporation
 * software or services.
 * Ping Identity Corporation only offers such software or services to legal entities
 * who have entered into a binding license agreement with Ping Identity Corporation.
 */
package com.sun.identity.agents.custom;

import static org.forgerock.agents.debug.AgentDebug.logTrace;

import javax.servlet.http.HttpServletRequest;

import org.forgerock.agents.util.Utils;

import com.sun.identity.agents.arch.AgentConfiguration;
import com.sun.identity.agents.arch.AgentException;
import com.sun.identity.agents.arch.Manager;
import com.sun.identity.agents.filter.AmFilterMode;
import com.sun.identity.agents.filter.AmFilterRequestContext;
import com.sun.identity.agents.filter.AmFilterResult;
import com.sun.identity.agents.filter.AmFilterTaskHandler;
import com.sun.identity.agents.filter.IBaseAuthnContext;

/**
 * This is an example of a custom self-redirect task handler.  It is essentially the same as the inbound task
 * handler.
 */
@SuppressWarnings("unused")
public class CustomSelfRedirectTaskHandler extends AmFilterTaskHandler {

    public CustomSelfRedirectTaskHandler(Manager manager) {
        super(manager);
    }

    @Override
    public void initialize(IBaseAuthnContext context) throws AgentException {
        super.initialize(context);
    }

    @Override
    public boolean isActive() {
        return true;
    }

    @Override
    public String getHandlerName() {
        return "Custom self redirect task handler";
    }

    @Override
    public AmFilterResult process(AmFilterRequestContext context) {

        String applicationName = Utils.getApplicationName(context);
        AmFilterMode amFilterMode = AgentConfiguration.getTheFilterMode(applicationName);
        HttpServletRequest request = context.getHttpServletRequest();

        logTrace("Hello from {}, application name {}, filter mode {}, {} {}",
                getHandlerName(), applicationName, amFilterMode,
                request.getMethod(), request.getRequestURI());

        // return null to continue to the other task handlers (until one returns a non null value)
        // return AmFilterResultStatus.STATUS_CONTINUE to grant access (continue to the next filter after the agent)
        // return AmFilterResultStatus.STATUS_REDIRECT to redirect somewhere else
        // return AmFilterResultStatus.STATUS_FORBIDDEN to deny access
        // return AmFilterResultStatus.STATUS_SERVE_DATA to serve up data to the browser
        // return AmFilterResultStatus.STATUS_SERVER_ERROR to abort the request with a 500 server error
        //
        return null;
    }
}

Example custom inbound task handler

/*
 * Copyright © 2019 - 2024 Ping Identity Corporation
 * This code is to be used exclusively in connection with Ping Identity Corporation
 * software or services.
 * Ping Identity Corporation only offers such software or services to legal entities
 * who have entered into a binding license agreement with Ping Identity Corporation.
 */
package com.sun.identity.agents.custom;

import static org.forgerock.agents.debug.AgentDebug.logTrace;

import javax.servlet.http.HttpServletRequest;

import org.forgerock.agents.util.Utils;

import com.sun.identity.agents.arch.AgentConfiguration;
import com.sun.identity.agents.arch.AgentException;
import com.sun.identity.agents.arch.Manager;
import com.sun.identity.agents.filter.AmFilterMode;
import com.sun.identity.agents.filter.AmFilterRequestContext;
import com.sun.identity.agents.filter.AmFilterResult;
import com.sun.identity.agents.filter.AmFilterTaskHandler;
import com.sun.identity.agents.filter.IBaseAuthnContext;

/**
 * This is an example of a custom inbound task handler
 */
@SuppressWarnings("unused")
public class CustomInboundTaskHandler extends AmFilterTaskHandler {

    public CustomInboundTaskHandler(Manager manager) {
        super(manager);
    }

    @Override
    public void initialize(IBaseAuthnContext context) throws AgentException {
        super.initialize(context);
    }

    @Override
    public boolean isActive() {
        return true;
    }

    @Override
    public String getHandlerName() {
        return "Custom inbound task handler";
    }

    @Override
    public AmFilterResult process(AmFilterRequestContext context) {

        String applicationName = Utils.getApplicationName(context);
        AmFilterMode amFilterMode = AgentConfiguration.getTheFilterMode(applicationName);
        HttpServletRequest request = context.getHttpServletRequest();

        logTrace("Hello from {}, application name {}, filter mode {}, {} {}",
                getHandlerName(), applicationName, amFilterMode,
                request.getMethod(), request.getRequestURI());

        // return null to continue to the other task handlers (until one returns a non null value)
        // return AmFilterResultStatus.STATUS_CONTINUE to grant access (continue to the next filter after the agent)
        // return AmFilterResultStatus.STATUS_REDIRECT to redirect somewhere else
        // return AmFilterResultStatus.STATUS_FORBIDDEN to deny access
        // return AmFilterResultStatus.STATUS_SERVE_DATA to serve up data to the browser
        // return AmFilterResultStatus.STATUS_SERVER_ERROR to abort the request with a 500 server error
        //
        return null;
    }
}

Example of how to override the ServiceResolver class

/*
 * Copyright © 2019 - 2024 Ping Identity Corporation
 * This code is to be used exclusively in connection with Ping Identity Corporation
 * software or services.
 * Ping Identity Corporation only offers such software or services to legal entities
 * who have entered into a binding license agreement with Ping Identity Corporation.
 */
package com.sun.identity.agents.custom;

import java.util.ArrayList;
import java.util.List;

import com.sun.identity.agents.arch.ServiceResolver;

/**
 * This is an example of how to override the ServiceResolver class to provide your own custom task handlers.  To use
 * this example class, place the following in the custom properties on the advanced tab in the Java Agents profile:
 * <p></p>
 * org.forgerock.agents.service.resolver.class.name=com.sun.identity.agents.custom.CustomServiceResolverExample
 * <p></p>
 * and restart the agent.
 */
@SuppressWarnings("unused")
public class CustomServiceResolverExample extends ServiceResolver {

    @Override
    public List<String> getPreInboundTaskHandlers() {
        List<String> result = new ArrayList<>();
        result.add(CustomInboundTaskHandler.class.getName());
        return result;
    }

    @Override
    public List<String> getPostInboundTaskHandlers() {
        return new ArrayList<>();
    }

    @Override
    public List<String> getPreSelfRedirectHandlers() {
        List<String> result = new ArrayList<>();
        result.add(CustomSelfRedirectTaskHandler.class.getName());
        return result;
    }

    @Override
    public List<String> getPostSelfRedirectHandlers() {
        return new ArrayList<>();
    }

    @Override
    public List<String> getPreFilterResultHandlers() {
        List<String> result = new ArrayList<>();
        result.add(CustomFilterResultTaskHandler.class.getName());
        return result;
    }

    @Override
    public List<String> getPostFilterResultHandlers() {
        return new ArrayList<>();
    }
}