Sun Java System Access Manager 6 2005Q1 Developer's Guide |
Chapter 9
Policy ManagementSun Java System Access Manager 6 2005Q1 includes a Policy Management feature that allows you to define, manage, and enforce policies that control access to protected resources. It allows administrators to configure and administer these conditions for applications, resources, and identities managed within the Access Manager deployment. This chapter explains the Policy Management feature and its architecture. It contains the following sections:
Policy SDKThe Policy SDK provides Java and C APIs to allow external applications to participate in its functionality. With the SDK, applications can determine privileges and manage policies.
The Sun Java System Access Manager Developer’s Reference provides summaries of data types, structures, and functions that make up the public Access Manager C APIs. You will find the Javadoc for Access Manager Java APIs in this location:
IdentityServer_base/SUNWam/docs/am_public_javadocs.jar
Java SDK For Policy
The crux of the Policy Service is the Java SDK. It defines the following packages:
- com.sun.identity.policy provides the APIs for administering (creating, deleting, modifying) and evaluating policies. It is used by the Access Manager console and/or the command line interface.
- com.sun.identity.policy.interfaces provides source interfaces used to implement custom subjects, conditions, referrals and resource comparators.
- com.sun.identity.policy.client are APIs used by remote Java applications that need to evaluate policies and get policy decisions.
Policy API For Java
The com.sun.identity.policy package provides the classes and methods to manage, administer and evaluate policies. They can be used by the Access Manager console or the amadmin command line interface tool. Select classes and methods are discussed in this section.
Policy Evaluation Classes
The following information introduces some of the classes that can be used to evaluate configured policies for access to a protected resource.
com.sun.identity.policy.PolicyEvaluator can be integrated into Java applications to evaluate policy privileges and provide policy decisions. This class provides support for both boolean and non-boolean type policies. A PolicyEvaluator is created by calling the constructor with a service name. Public methods of this class include:
- isAllowed—evaluates the policy associated with the given resource and returns a boolean value indicating whether the policy evaluation resulted in an allow or deny.
- Returns a boolean value of:
- Arguments:
- com.iplanet.sso.SSOToken: The SSOToken associated with the principal for which the policy will be evaluated.
- java.lang.String resourceName: A string representing the requested resource.
- java.lang.String actionName: The action for which the policy will be evaluated. In a typical web application scenario, the action could be GET or POST.
- java.util.Map envParameters: A map containing environment parameters that may be needed to successfully evaluate the associated policies.
- Exceptions:
- getPolicyDecision—evaluates the policy and ascertains privileges for non-boolean decisions. It returns a decision that gives a user permission to perform a specific action on a specific resource. This method can also check permissions for multiple actions.
- Returns com.sun.identity.policy.PolicyDecision.
- Arguments:
- com.iplanet.sso.SSOToken: The SSO token associated with the principal for which the policy will be evaluated.
- java.lang.String resourceName: A string representing the requested resource.
- java.util.Set actionName: A collection of actions for which the policy will be evaluated.
- java.util.Map envParameters: A map containing environment parameters that may be needed to successfully evaluate the associated policies.
- Exceptions:
- getResourceResult—obtains the policy and ascertains privileges for non-boolean decisions. Possible values for the scope of this method are self and subtree. self gets the policy decision for the specified resource only. subtree includes the policy decisions for all resources (defined in the policies) which are sub-resources of the specified resource.
To illustrate, the PolicyEvaluator class can be used to display the links for a list of resources to which an authenticated user has access. The getResourceResult method would be used to get the list of resources. The resourceName parameter would be http://host.domain:port which would return all the resources to which the user has access on that server. These resources are returned as a PolicyDecision based on the user’s defined policies. If the user is allowed to access resources on different servers, this method needs to be called for each server.
Note
Not all resources that have policy decisions are accessible to the user. The ActionDecision(s) contained in policy decisions carry this information.
com.sun.identity.policy.ProxyPolicyEvaluator allows a privileged user (top level administrator, organization administrator, policy administrator, or organization policy administrator) to get policy privileges and evaluate policy decisions for any user in their respective scope of administration. com.sun.identity.policy.ProxyPolicyEvaluatorFactory is the singleton class used to get ProxyPolicyEvaluator instances.
com.sun.identity.policy.client.PolicyEvaluator evaluates policies and provides policy decisions for remote applications which do not have a direct access to Directory Server (for example, if there is a firewall). The com.sun.identity.policy.client.PolicyEvaluator defined in PolicyEvaluator Class requires direct LDAP access to policies stored in Directory Server. This class com.sun.identity.policy.client.PolicyEvaluator is implemented using XML over HTTP(s). It stores a cache of policy decisions for faster responses and maintains the cache in sync with the Policy Service on the instance of Access Manager using the notification and polling mechanism.
Note
The PolicyEvaluator class can be used in a deployment container running Access Manager, or in a stand alone Java Virtual Machine (JVM) running the Access Manager SDK. Respective to the JVM, a property must be defined to point to serverconfig.xml which, in turn, points to Directory Server. This is done by launching the JVM with the following argument:
-D "com.iplanet.coreservices.configpath=/etc/opt/SUNWam/ config/ums"
Policy Management Classes
The following classes can be used by system administrators to manage policies in Access Manager. The interfaces for this functionality are also found in the com.sun.identity.policy package.
com.sun.identity.policy.PolicyManager is the top level administrator class for policy management, providing methods that allow an administrator to create, modify or delete an organization’s policies. The PolicyManager can be obtained by passing a privileged user’s session token or by passing a privileged user’s session token with an organization name. Some of this class’s more widely used methods include:
- getPolicyNames - retrieves all named policies created for the organization for which the policy manager was instantiated. This method can also take a pattern (filter) as an argument.
- getPolicy - retrieves a policy when given the policy’s name.
- addPolicy - adds a policy to the specified organization. If a policy with the same name already exists, it will be overwritten.
- removePolicy - removes a policy from the specified organization.
com.sun.identity.policy.Policy represents a policy definition with all its intended parts (rules, subjects, referrals and conditions). The policy object is saved in the data store only when the store method is called or if the addPolicy or replacePolicy methods from the PolicyManager class are invoked. This class contains methods to add, remove, replace or get any of the parts of a policy definition.
com.sun.identity.policy.PolicyEvent represents a happening in a policy that could potentially change the current access status. For example, a policy event would be created and passed to the registered policy listeners whenever there is a change in a policy rule. This class works with the PolicyListener class in the com.sun.identity.policy.interface package.
Policy Plugin API For Java
The following classes are used by service developers and policy administrators who need to provide additional policy features as well as support for legacy policies. The package for these classes is com.sun.identity.policy.interfaces. The interfaces include:
ResourceName
ResourceName provides methods to determine the hierarchy of the resource names for a determined service type. For example, these methods can check to see if two resources names are the same or if one is a sub-resource of the other.
Subject
Subject defines methods that can determine if an authenticated user (possessing an SSOToken) is a member of the given subject.
Referral
Referral defines methods used to delegate the policy definition or evaluation of a selected resource (and its sub-resources) to another organization or policy server.
Condition
Condition provides methods used to constrain a policy; for example, time of day or IP address. This interface allows the pluggable implementation of the conditions.
PolicyListener
PolicyListener defines an interface to register for policy events when a policy is added, removed or changed. It is used by the policy service to send notifications and by listeners to review policy change events.
C Library For Policy
Access Manager also provides a library of policy evaluation APIs to enable integration of the policy functionality into for C applications. The C library provides a comprehensive set of interfaces that query policy results of an authenticated user for a given action on a given resource. The result of the policy evaluation is called an action value and may not always be binary (allow/deny or yes/no); action values can also be non-boolean. For example, John Smith has a mailbox quota of 100MB. 100 is the value defined by a policy. As policy evaluation results in string values only, the policy evaluation returned is 100 numeric not 100MB. It is up to the application developer to define metrics for the values obtained appropriately.
Caution
Previous releases of Access Manager contained C libraries in IdentityServer_base/lib/capi. The capi directory is being deprecated, and is currently available for backward compatibility. It will be removed in the next release, and therefore it is highly recommended that existing application paths to this directory are changed and new applications do not access it. Paths include RPATH, LD_LIBRARY_PATH, PATH, compiler options, etc.)
As the first step of policy implementation, the API abstracts how a resource is represented by mandating that any resource be represented in a string format. For example, on a web server, resources may be represented as URLs. The policy evaluation engine cares only about the relative relevance of one resource to other. There are five relative relevances defined between two resources, namely: exact match, no match, subordinate match, superior match or exact pattern match. Having represented the resources in string format, the service developer must provide interfaces that establish the relevant relationship between resources.
Note
Exact pattern match is a special case where resources may be represented collectively as patterns. The information is abstracted from the policy service and the comparison operation must take a boolean parameter to trigger a pattern matched comparison. During the caching of policy information, the policy engine does not care about patterns, whereas during policy evaluation, the comparisons are pattern sensitive.
The service developer must also provide a method to extract the root of the given resource. For example, in a URL, the protocol://identity_server_host.domain_name:port portion represents the root. The three functions (has_patterns, get_resource_root and compare_urls) are specializations of resource representations. The set of characteristics needed to define a resource is called a resource trait. Resource traits are taken as a parameter during service initialization in the am_resource_traits_t structure. Using the resource traits, the policy service constructs a resource graph for policy evaluation. In a web server policy sense, the relation between all the resources in the system spans out like a tree with the protocol://identity_server_host.domain_name:port/ being the root of the tree.
Note
The policy management system is generic and makes no assumptions about any particular policy definition requirement.
Policy Evaluation API for C
Two opaque data structures are defined: am_map_t and am_properties_t. am_map_t provides a key to multiple value mapping and am_properties_t provides a key to single value mapping. am_properties_t provides the additional functionality of loading a configuration file and getting values of specific data types. These are simple data structures that are only used for information exchange to and from the policy evaluation interfaces.
Extending the Policy Management FeatureOut of the box, Access Manager provides the URL Policy Agent service for policy enforcement. However, you can use the Policy API to extend the functionality of the default policy service. Through the API, you can create a new policy service to fit your needs.
Access Manager provides a collection of sample files to illustrate how to use the Policy API. This section explains how to use the samples to develop and add custom subjects, conditions and referrals to existing policy, to programatically construct new policies, and to develop and run policy evaluation programs.In order to successfully execute the policy samples, the following tasks must be completed in order:
The samples and all associated files are located in the following directories:
Compiling the Policy Samples
Before you can use the files included with the samples, you must compile them. To compile the samples:
Adding the Policy Service to Access Manager
Before you use the API to customize the interface, you must add the SampleWebService.xml file to Access Manager. For information on adding new policy services, see the “Policy Management” chapter of the Access Manager Administration Guide.
Developing Custom Subjects, Conditions and Referrals
The Policy API provides a means to customize a policy service interface, which provides the variables that define the policy itself. This sample shows how to customize the subject, condition and rule interfaces for SampleWebService.
The interfaces used to implement the customization are as follows:
- SampleSubject.java - Implements the Subject interface. This subject applies to all authenticated users who have valid SSOTokens.
- SampleConditon.java - Implements the Condition interface. This condition makes the policy applicable to users whose name length is grater or equal to the length spcified in the condition.
- SampleReferral.java - Implements the Referral interface. This referral retrieves the referral policy decision from the SampleReferral.properties file. This file is located in the same directory as the rest of the sample files.
The subject, condition and referral implementations need to be added to iPlanetAMPolicyServicea and iPlanetAMPolicyConfigService services in order to make them available for policy definitions. (These services are loaded into Access Manager during installation.) To add the sample implementations to the policy framework, you must first modify the iPlanetAMPolicy service and iPlanetAMPolicyConfig service. The policy samples provide a modified XML file for use with each service. The iPlanetAMPolicyServicea service uses amPolicy.xml and the iPlanetAMPolicyConfigService uses amPolicyConfig.xml.
The following XML attribute values in amPolicyConfig.xml must be changed to reflect your installation before they are loaded to Access Manager:
When setting the iplanet-am-policy-config-ldap-bind-password attribute, the encrypted value must be used. The ampassword command can be used to generate encrypted password (for more information, see “The ampassword Command Line Tool” in the Access Manager Administration Guide”). Alternatively, they can be set to correct values when the policy configuration service is registered for the organizations.
To Load the Modified Services
- Back up iPlanetAMPolicy and iPlanetAMPolicyConfig services using the db2ldif utility. For example:
cd DirectoryServer_base/slapd-hostname
db2ldif -n userRoot -s "ou=iPlanetAMPolicyService,ou=services,root_suffix"
db2ldif -n userRoot -s "ou=iPlanetAMPolicyConfigService,ou=services,root_suffix"
- Remove the existing iPlanetAMPolicy and iPlanetAMPolicyConfig services by running the following commands:
IdentityServer_base/SUNWam/bin/amadmin
--runasdn "uid=amAdmin,ou=People,default_org,root_suffix"
--password password
--deleteservice iPlanetAMPolicyService
IdentityServer_base/SUNWam/bin/amadmin
--runasdn "uid=amAdmin,ou=People,<default_org>,root_suffix"
--password password
--deleteservice iPlanetAMPolicyConfigService
- Add the modified services back to the server. The XML attributes values must be modified to your installation before running these commands):
IdentityServer_base/SUNWam/bin/amadmin
--runasdn "uid=amAdmin,ou=People,default_org,root_suffix"
--password password
--schema IdentityServer_base/SUNWam/samples/policy/amPolicy.xml
IdentityServer_base/SUNWam/bin/amadmin
--runasdn "uid=amAdmin,ou=People,default_org,root_suffix"
--password password
--schema IdentityServer_base/SUNWam/samples/policy/amPolicyConfig.xml
The original services XML files for these two services are located in IdentityServer_base/SUNWam/config/xml.
- Change the properties files with the following commands:
cd IdentityServer_base/SUNWam/locale
mv amPolicy.properties amPolicy.properties.bak
mv amPolicy_en.properties amPolicy_en.properties.bak
mv amPolicyConfig.properties amPolicyConfig.properties.bak
mv amPolicyConfig_en.properties amPolicyConfig_en.properties.bak
cp IdentityServer_base/SUNWam/samples/policy/amPolicy.properties
cp IdentityServer_base/SUNWam/samples/policy/amPolicy_en.properties
cp IdentityServer_base/SUNWam/samples/policy/amPolicyConfig.properties
cp IdentityServer_base/SUNWam/samples/policy/amPolicyConfig_en.properties
- To deploy the sample plugins copy SampleSubject.class, SampleCondition.class and SampleReferral.class from the sample directory to IdentityServer_base/SUNWam/lib.
- Restart Access Manager.
- Login into Access Manager console and register policy configuration service to the organization. (For more information, see the “Policy Management” chapter of the Access Manager Administration Guide.)
You can also use amadmin tool to register policy configuration service to organizations.
- Enter the LDAP Bind password for the LDAP Bind User.
The sample subject, condition and referral implementations are now available for policy management through the Access Manager console or the amadmin tool.
Creating Policies for the Service
After you add the SampleWebService service to Access Manager and develop the custom interfaces, you need to create a policy for the service. Access Manager provides the following sample policy definitions for the SampleWebService:
For information on adding new policy services, see the “Policy Management” chapter of the Access Manager Administration Guide.
Developing and Running Policy Evaluation Programs
The Policy API provides a Policy Evaluation API that allows you to write a policy evaluation program to ensure that the policy service, and the policy definitions that the service contains, function properly.
The Policy Evaluation API has one java class, PolicyEvaluator, and the package for this class is com.sun.identity.policy.PolicyEvaluator. Based on this class, Access Manager provides a sample policy evaluation program called PolicyEvaluation.java.
The sample policy evaluation program uses the PolicyEvaluation.properties file, in which you specify the input for the evaluation program such as service name, action names, condition environment parameters, user name, user password and so forth. The following properties can be set as input to the evaluation program:
- Set the value of pe.servicename to the service name (SampleWebService).
- Set the pe.resoucename to the resource name against which you want to evaluate the policy.
- Specify the action names in the pe.actionnames. Separate the action names with ':'. If you want to get all the action values, you can simply leave the pe.actionnames blank.
- Set other required properties like pe.username, pe.password.
- Set the optional properties pe.authlevel, pe.authscheme, pe.requestip, pe.dnsname, pe.time if you use the corresponding conditions in your policy definitions.
To Run the Policy Evaluation Program
Constructing Policies Programmatically
The Policy API provides Policy Management API that allows you to programatically create, add, update and remove policies. Access Manager provides a sample program, PolicyCreator.java, which demonstrates how to construct policies and add them to the policy store. For your reference, the PolicyCreator.java code is listed at the end of this section.
In this sample, the following two policies are created:
To Run PolicyCreator.java
- Compile sample Java programs. See Compiling the Policy Samples for more information.
- Set the environment variable LD_LIBRARY_PATH to /usr/lib/mps/secv1.
In the Access Manager console, create a suborganization called org1, a user called user1, a group called group1 and role called role1. Make sure that all of these identity objects are created in your top-level organization. For more information on creating these objects, see the Access Manager Administration Guide.
PolicyCreator.java
The following section lists the PolicyCreator.java code.
Code Example 9-2
import com.sun.identity.policy.PolicyManager;
import com.sun.identity.policy.ReferralTypeManager;
import com.sun.identity.policy.SubjectTypeManager;
import com.sun.identity.policy.ConditionTypeManager;
import com.sun.identity.policy.Policy;
import com.sun.identity.policy.Rule;
import com.sun.identity.policy.interfaces.Referral;
import com.sun.identity.policy.interfaces.Subject;
import com.sun.identity.policy.interfaces.Condition;
import com.sun.identity.policy.PolicyException;
import com.iplanet.sso.SSOToken;
import com.iplanet.sso.SSOException;
import java.util.Set;
import java.util.HashSet;
import java.util.Map;
import java.util.HashMap;
public class PolicyCreator {
public static final String DNS_NAME="DnsName";
public static final String DNS_VALUE="*.red.iplanet.com";
public static final String START_TIME="StartTime";
public static final String START_TIME_VALUE="08:00";
public static final String END_TIME="EndTime";
public static final String END_TIME_VALUE="21:00";
public static final String AUTH_LEVEL="AuthLevel";
public static final String AUTH_LEVEL_VALUE="0";
public static final String AUTH_SCHEME="AuthScheme";
public static final String AUTH_SCHEME_VALUE="LDAP";
private String orgDN;
private SSOToken ssoToken;
private PolicyManager pm;
private PolicyCreator() throws PolicyException, SSOException {
BaseUtils.loadProperties();
orgDN = BaseUtils.getProperty("pe.orgname");
System.out.println("orgDN = " + orgDN);
ssoToken = BaseUtils.getToken();
pm = new PolicyManager(ssoToken, orgDN);
}
public static void main(String[] args) {
try {
PolicyCreator pc = new PolicyCreator();
pc.addReferralPolicy();
pc.addNormalPolicy();
System.exit(0);
} catch(Exception e) {
e.printStackTrace();
}
}
private void addNormalPolicy() throws PolicyException, SSOException {
System.out.println("Creating normal policy in org:" + orgDN);
PolicyManager pm = new PolicyManager(ssoToken, orgDN);
SubjectTypeManager stm = pm.getSubjectTypeManager();
ConditionTypeManager ctm = pm.getConditionTypeManager();
Policy policy = new Policy("policy1", "policy1 description");
Map actions = new HashMap(1);
Set values = new HashSet(1);
values.add("allow");
actions.put("GET", values);
String resourceName = "http://myhost.com:80/hello.html";
Rule rule = new Rule("rule1", "iPlanetAMWebAgentService",
resourceName, actions);
policy.addRule(rule);
Subject subject = stm.getSubject("Organization");
Set subjectValues = new HashSet(1);
subjectValues.add(orgDN);
subject.setValues(subjectValues);
policy.addSubject("organization", subject);
subject = stm.getSubject("LDAPUsers");
subjectValues = new HashSet(1);
String userDN = "uid=user1,ou=people" + "," + orgDN;
subjectValues.add(userDN);
subject.setValues(subjectValues);
policy.addSubject("ldapusers", subject);
subject = stm.getSubject("LDAPGroups");
subjectValues = new HashSet(1);
String groupDN = "cn=group1,ou=groups" + "," + orgDN;
subjectValues.add(groupDN);
subject.setValues(subjectValues);
policy.addSubject("ldapgroups", subject);
subject = stm.getSubject("LDAPRoles");
subjectValues = new HashSet(1);
String roleDN = "cn=role1" + "," + orgDN;
subjectValues.add(roleDN);
subject.setValues(subjectValues);
policy.addSubject("ldaproles", subject);
subject = stm.getSubject("IdentityServerRoles");
subjectValues = new HashSet(1);
roleDN = "cn=role1" + "," + orgDN;
subjectValues.add(roleDN);
subject.setValues(subjectValues);
policy.addSubject("is-roles", subject);
Condition condition = ctm.getCondition("IPCondition");
Map conditionProperties = new HashMap(1);
Set propertyValues = new HashSet(1);
propertyValues.add(DNS_VALUE);
conditionProperties.put(DNS_NAME, propertyValues);
condition.setProperties(conditionProperties);
policy.addCondition("ip_condition", condition);
condition = ctm.getCondition("SimpleTimeCondition");
conditionProperties = new HashMap(1);
propertyValues = new HashSet(1);
propertyValues.add(START_TIME_VALUE);
conditionProperties.put(START_TIME, propertyValues);
propertyValues = new HashSet(1);
propertyValues.add(END_TIME_VALUE);
conditionProperties.put(END_TIME, propertyValues);
condition.setProperties(conditionProperties);
policy.addCondition("time_condition", condition);
condition = ctm.getCondition("AuthLevelCondition");
conditionProperties = new HashMap(1);
propertyValues = new HashSet(1);
propertyValues.add(AUTH_LEVEL_VALUE);
conditionProperties.put(AUTH_LEVEL, propertyValues);
condition.setProperties(conditionProperties);
policy.addCondition("auth_level_condition", condition);
condition = ctm.getCondition("AuthSchemeCondition");
conditionProperties = new HashMap(1);
propertyValues = new HashSet(1);
propertyValues.add(AUTH_SCHEME_VALUE);
conditionProperties.put(AUTH_SCHEME, propertyValues);
condition.setProperties(conditionProperties);
policy.addCondition("auth_scheme_condition", condition);
pm.addPolicy(policy);
System.out.println("Created normal policy");
}
private void addReferralPolicy()
throws PolicyException, SSOException {
System.out.println("Creating referral policy for org1");
ReferralTypeManager rtm = pm.getReferralTypeManager();
String subOrgDN = "o=org1" + "," + orgDN;
Policy policy = new Policy("refpolicy1", "ref to org1" true);
Map actions = new HashMap(1);
Rule rule = new Rule("rule1", "iPlanetAMWebAgentService","http://myhost.com:80/org1", actions);
policy.addRule(rule);
Referral referral = rtm.getReferral("SubOrgReferral");
Set referralValues = new HashSet(1);
referralValues.add(subOrgDN);
referral.setValues(referralValues);
policy.addReferral("ref to org1" , referral);
pm.addPolicy(policy);
System.out.println("Created referral policy for org1");
}
}
PolicyCreator.java