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 theorg.forgerock.openam.entitlement.EntitlementModule
interface. In the sample, this class registersSampleAttribute
,SampleCondition
, andSampleSubject
.The services file,
org.forgerock.openam.entitlement.EntitlementModule
, holds the fully qualified class name of theEntitlementModule
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:
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.
When the build is complete, copy the
policy-evaluation-plugin-7.0.2.jar
file to theWEB-INF/lib
directory where you deployed AM:$
cp target/*.jar /path/to/tomcat/webapps/openam/WEB-INF/lib/
Edit the
/path/to/tomcat/webapps/openam/XUI/locales/en/translation.json
file to update the user interface to include the custom subject and environment conditions:Locate the line that contains the following text:
"subjectTypes": {
Insert the following text after the line you located in the previous step:
"SampleSubject": { "title": "Sample Subject", "props": { "name": "Name" } },
Locate the line that contains the following text:
"conditionTypes": {
Insert the following text after the line you located in the previous step:
"SampleCondition": { "title": "Sample Condition", "props": { "nameLength": "Minimum username length" } },
If you require additional translations under
/path/to/tomcat/webapps/openam/XUI/locales
, modify othertranslation.json
files as needed.Clear your browser's cache and restart your browser.
Clearing the cache and refreshing the browser is required when you modify the
translation.json
file.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/authenticate'
{ "tokenId":"AQIC5wM2...", "successUrl":"/openam/console", "realm":"/" }
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:
Property | Value |
---|---|
Name | Sample Policy |
Resource Type | URL |
Resources | Use the *://*:*/* resource template to specify the resource http://www.example.com:80/* . |
Actions | Allow 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/authenticate'
{ "tokenId":"AQIC5wM2...", "successUrl":"/openam/console", "realm":"/" }
$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/authenticate'
{ "tokenId":"AQIC5wM...TU3OQ*", "successUrl":"/openam/console", "realm":"/" }
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 ...