Customizing Policy Evaluation With a Plug-In

AM policies let you restrict access to resources based both on identity and group membership, and also on a range of conditions including session age, authentication chain or module used, authentication level, realm, session properties, IP address and DNS name, user profile content, resource environment, date, day, time of day, and time zone. Yet, some deployments require further distinctions for policy evaluation. This section explains how to customize policy evaluation for deployments with particular requirements not met by built-in AM functionality.

This section shows how to build and use a custom policy plugin that implements a custom subject condition, a custom environment condition, and a custom resource attribute.

About the Sample Plugin

The AM policy framework lets you build plugins that extend subject conditions, environment conditions, and resource attributes.

For information on downloading and building AM sample source code, see How do I access and build the sample code provided for AM (All versions)? in the Knowledge Base.

Get a local clone so that you can try the sample on your system. You will find the relevant files under the /path/to/openam-samples-external/policy-evaluation-plugin directory.

pom.xml

Apache Maven project file for the module

This file specifies how to build the sample policy evaluation plugin, and also specifies its dependencies on AM components.

src/main/java/org/forgerock/openam/examples/SampleAttributeType.java

Extends the com.sun.identity.entitlement.ResourceAttribute interface, and shows an implementation of a resource attribute provider to send an attribute with the response.

src/main/java/org/forgerock/openam/examples/SampleConditionType.java

Extends the com.sun.identity.entitlement.EntitlementCondition interface, and shows an implementation of a condition that is the length of the user name.

A condition influences whether the policy applies for a given access request. If the condition is fulfilled, then AM includes the policy in the set of policies to evaluate in order to respond to a policy decision request.

src/main/java/org/forgerock/openam/examples/SampleSubjectType.java

Extends the com.sun.identity.entitlement.EntitlementSubject interface, and shows an implementation that defines a user to whom the policy applies.

A subject, like a condition, influences whether the policy applies. If the subject matches in the context of a given access request, then the policy applies.

src/main/java/org/forgerock/openam/examples/SampleEntitlementModule.java, src/main/resources/META-INF/services/org.forgerock.openam.entitlement.EntitlementModule

These files serve to register the plugin with AM.

The Java class, SampleEntitlementModule, implements the org.forgerock.openam.entitlement.EntitlementModule interface. In the sample, this class registers SampleAttribute, SampleCondition, and SampleSubject.

The services file, org.forgerock.openam.entitlement.EntitlementModule, holds the fully qualified class name of the EntitlementModule that registers the custom implementations. In this case, org.forgerock.openam.entitlement.EntitlementModule.

For an explanation of service loading, see the ServiceLoader API specification.

Building the Sample Plugin

Follow the steps in this procedure to build the sample plugin:

To Build the Sample Plugin
  1. If you have not already done so, download and build the samples.

    For information on downloading and building AM sample source code, see How do I access and build the sample code provided for AM (All versions)? in the Knowledge Base.

  2. When the build is complete, copy the policy-evaluation-plugin-7.1.4.jar file to the WEB-INF/lib directory where you deployed AM:

    $ cp target/*.jar /path/to/tomcat/webapps/openam/WEB-INF/lib/
  3. Update the user UI to include the custom subject and environment conditions.

    For more information, see the UI Customization Guide.

    1. Locate the line that contains the following text:

      "subjectTypes": {

    2. Insert the following text after the line you located in the previous step:

      "SampleSubject": {
          "title": "Sample Subject",
          "props": {
              "name": "Name"
          }
      },

    3. Locate the line that contains the following text:

      "conditionTypes": {

    4. Insert the following text after the line you located in the previous step:

      "SampleCondition": {
          "title": "Sample Condition",
          "props": {
              "nameLength": "Minimum username length"
          }
      },

  4. If your UI supports multiple locales, modify the translation.json files for those locales, as needed.

  5. When you have rebuilt the UI, clear your browser's cache and restart your browser.

  6. Restart AM or the container in which it runs.

Adding Custom Policy Implementations to Existing Policy Sets

In order to use your custom policy in existing policy sets, you must update the policy sets. Note that you cannot update a policy set that already has policies configured. When there are already policies configured for a policy set, you must instead first delete the policies, and then update the policy set.

Update the iPlanetAMWebAgentService policy set in the top level realm of a fresh installation. First, authenticate to AM as the amAdmin user:

$ curl \
--request POST \
--header "Content-Type: application/json" \
--header "X-OpenAM-Username: amadmin" \
--header "X-OpenAM-Password: password" \
--header "Accept-API-Version: resource=2.0, protocol=1.0" \
'https://openam.example.com:8443/openam/json/realms/root/realms/alpha/authenticate'
{
    "tokenId":"AQIC5wM2...",
    "successUrl":"/openam/console",
    "realm":"/alpha"
}

Then update the iPlanetAMWebAgentService policy set by adding the SampleSubject subject condition and the SampleCondition environment condition:

$ curl \
--request PUT \
--header "iPlanetDirectoryPro: AQIC5wM2..." \
--header "Content-Type: application/json" \
--header "Accept-API-Version: resource=1.0" \
--data '{
"name": "iPlanetAMWebAgentService",
"conditions": [
    "LEAuthLevel",
    "Script",
    "AuthenticateToService",
    "SimpleTime",
    "AMIdentityMembership",
    "OR",
    "IPv6",
    "IPv4",
    "SessionProperty",
    "AuthScheme",
    "AuthLevel",
    "NOT",
    "AuthenticateToRealm",
    "AND",
    "ResourceEnvIP",
    "LDAPFilter",
    "OAuth2Scope",
    "Session",
    "SampleCondition"
],
"subjects": [
    "NOT",
    "OR",
    "JwtClaim",
    "AuthenticatedUsers",
    "AND",
    "Identity",
    "NONE",
    "SampleSubject"
],
"applicationType": "iPlanetAMWebAgentService",
"entitlementCombiner": "DenyOverride"
}' https://openam.example.com:8443/openam/json/realms/root/applications/iPlanetAMWebAgentService

Trying the Sample Subject and Environment Conditions

Using the AM console, add a policy to the iPlanetAMWebAgentService policy set in the top level realm that allows HTTP GET access for URLs based on the template http://www.example.com:80/* and uses the custom subject and environment conditions.

Create the policy with the following properties:

Sample Policy Properties
PropertyValue
NameSample Policy
Resource TypeURL
Resources

Use the *://*:*/*resource template to specify the resource http://www.example.com:80/*.

ActionsAllow GET
Subject Conditions

Add a subject condition of type Sample Subject and a name of demo so that the demo user is the only user who can access the resource.

Environment Conditions

Add an environment condition of type Sample Condition and a minimum username length of 4 so that only users with a username length of 4 characters or greater can access the resource.


With the policy in place, authenticate both as a user who can request policy decisions and also as a user trying to access a resource. Both of these calls return tokenId values for use in the policy decision request.

$ curl \
--request POST \
--header "Content-Type: application/json" \
--header "X-OpenAM-Username: amadmin" \
--header "X-OpenAM-Password: password" \
--header "Accept-API-Version: resource=2.0, protocol=1.0" \
'https://openam.example.com:8443/openam/json/realms/root/realms/alpha/authenticate'
{
    "tokenId":"AQIC5wM2...",
    "successUrl":"/openam/console",
    "realm":"/alpha"
}
  $ curl \
--request POST \
--header "Content-Type: application/json" \
--header "X-OpenAM-Username: demo" \
--header "X-OpenAM-Password: Ch4ng31t" \
--header "Accept-API-Version: resource=2.0, protocol=1.0" \
'https://openam.example.com:8443/openam/json/realms/root/realms/alpha/authenticate'
{
    "tokenId":"AQIC5wM...TU3OQ*",
    "successUrl":"/openam/console",
    "realm":"/alpha"
}

Use the administrator tokenId as the header of the policy decision request, and the user tokenId as the subject ssoToken value.

$ curl \
--request POST \
--header "Content-Type: application/json" \
--header "Accept-API-Version: resource=2.1" \
--header "iPlanetDirectoryPro: AQIC5wM2LY4Sfcw..." \
--data '{
    "subject":{
        "ssoToken":"AQIC5wM2LY4Sfcy..."
    },
    "resources":[
        "http://www.example.com:80/index.html"
    ],
    "application":"iPlanetAMWebAgentService"
}' \
"https://openam.example.com:8443/openam/json/realms/root/policies?_action=evaluate"
{
   "resource": "http://www.example.com:80/index.html",
   "actions": {
       "GET": true
   },
   "attributes": {},
   "advices": {}
}

Notice that the actions returned from the policy evaluation call are set in accordance with the policy.

Trying the Sample Resource Attributes

The sample custom policy plugin can have AM return an attribute with the policy decision. In order to make this work, list the resource type for the URL resource type to obtain its UUID, and then update your policy to return a test attribute:

$ curl \
--request GET \
--header "iPlanetDirectoryPro: AQIC5wM2..." \
--header "Accept-API-Version: resource=1.0" \
https://openam.example.com:8443/openam/json/realms/root/resourcetypes?_queryFilter=name%20eq%20%22URL%22
{
    "result":[
        {
            "uuid":"URL-resource-type-UUID",
            "name":"URL",
            "description":"The built-in URL Resource Type available policies.",
            "patterns":["*://*:*/*","*://*:*/*?*"],
            ...
        }
    ],
    "resultCount":1,
    "pagedResultsCookie":null,
    "totalPagedResultsPolicy":"NONE",
    "totalPagedResults":-1,f
    "remainingPagedResults":0
}

When you now request the same policy decision as before, AM returns the test attribute that you configured in the policy.

$ curl \
--request POST \
--header "Content-Type: application/json" \
--header "Accept-API-Version: resource=2.1" \
--header "iPlanetDirectoryPro: AQIC5wM2LY4Sfcw..." \
--data '{
    "subject":{
        "ssoToken":"AQIC5wM2LY4Sfcy..."
    },
    "resources":[
        "http://www.example.com:80/index.html"
    ],
    "application":"iPlanetAMWebAgentService"
}' \
"https://openam.example.com:8443/openam/json/realms/root/policies?_action=evaluate"
{
    "resource": "http://www.example.com/profile",
    "actions": {
        "GET": true
    },
    "attributes": {
    "test": [
        "sample"
     ]
},
"advices": {}
}

Extending the ssoadm Classpath

After customizing your AM deployment to use policy evaluation plugins, inform ssoadm users to add the jar file containing the plugins to the classpath before running policy management subcommands.

To add a jar file to the ssoadm classpath, set the CLASSPATH environment variable before running the ssoadm command.

$ export CLASSPATH=/path/to/jarfile:$CLASSPATH
$ ssoadm ...

Read a different version of :