Back | Next | Contents Cams Programmer's Guide

Cams Access Control Rules

This document describes the use of the Cams Access Control Rules API, which enables you to implement custom access control rules based on date, time, business rules, user profile information, database values, and more. Creating custom access control rules facilitates their centralization, security, and reuse across multiple enterprise resources and applications.

Overview of Cams Access Control Rules

Cams uses access control rules (ACRs) to implement the business logic for controlling access to protected resources. The access control rules provided with the standard Cams distribution include:

These ACRs are also known as the Cams intrinsic access control rules because they are available for all security domains and cannot be replaced or removed. If these rules are not sufficient for your needs, you can add new access control rules to Cams that grant or deny access based on:

Besides controlling access to protected resources, Cams access control rules must also be:

  1. Stored as part of a security domain's access control policy
  2. Loaded from a security domain's access control policy
  3. Removed from persistent access control policy storage

To support these requirements, you'll need to create and register a set of classes for each custom access control rule that you create.

Access Control Rules API Reference

The following classes make up the Access Control Rule API:

Before getting into more detail on these classes, you'll need a little more context on the environment within which access control rules are executed and managed.

Access control rules are defined within the scope of a Cams security domain's access control policy, which defines the resources being protected and the rules that control access to them. Within each access control policy, an access control rule library manages access control rule types and instances.

Figure 1 shows the relationships between some internal Cams classes and Access Control Rule API classes. The interfaces shown in green are the ones you'll implement to plug a new access control rule into Cams. Summarizing these relationships: a SecurityDomain has an AccessControlService, which loads an AccessControlPolicy (by default from an XML file). Within the AccessControlPolicy, an AccessControlRuleLibrary stores information about AccessControlRuleTypes and AccessControlRule instances. An AccessControlRule is an instance of an AccessControlRuleType, which has an AccessControlRulePersistenceManager, which is responsible for creating, loading, storing, and removing AccessControlRules from persistent storage.

Figure 1 - Relationships between Cams Access Control Rule API classes

Access Control Rule API Classes Overview

This section summarizes the roles of Access Control Rule API classes.
com.cafesoft.cams.access.AccessControlRule
com.cafesoft.cams.access.AbstractAccessControlRule

AccessControlRule is the basic interface that must be implemented by all AccessControlRules. Methods include a way to set/get an AccessControlRule's identifier (which must be unique within a security domain's AccessControlPolicy), a way to set/get a textual description, and a method to evaluate the rule using InternalAccessControlRequest/InternalAccessControlResponse parameters. For convenience, you can extend AbstractAccessControlRule to implement your own AccessControlRules. AbstractAccessControlRule implements the generic AccessControlRule accessors and mutators, leaving the evaluate method (and any other custom methods) for your implementation.

com.cafesoft.cams.access.InternalAccessControlRequest
com.cafesoft.cams.access.InternalAccessControlResponse

InternalAccessControlRequest and InternalAccessControlResponse are the interfaces to parameters passed to AccessControlRules during evaluation. The InternalAccessControlRequest provides access to information about the resource being accessed including: the resource type, resource identifier, requested action, remote host information, authenticated user session, and more. The InternalAccessControlResponse interface provides AccessControlRules with the means to customize certain responses to the Cams security engine.

com.cafesoft.cams.access.EvaluationException

If an AccessControlRule experiences a serious error condition during evaluation, it should throw an EvaluationException. This Exception may indicate that a major precondition to evaluating the AccessControlRule is not met or that some other critical runtime state is not correct.

com.cafesoft.cams.access.AccessControlRulePersistenceManager
com.cafesoft.cams.PersistenceException

AccessControlRulePersistenceManager is an interface for Objects that are responsible for:

PersistenceException is used to communicate errors that might be encountered during use of an AccessControlRulePersistenceManager.

Access Control Rules Persistence

By default, Cams use an XML-formatted file to persist an access control policy and the access control rules within it, but the Cams design also enables persistence to relational databases, LDAP servers, and more. Although access control rule implementations are independent of storage type, AccessControlRulePersistenceManager implementations are not.

For XML storage, AccessControlRules are defined within a security domain-specific XML file named access-control-policy.xml. A factory class (registered within security-domain.xml) parses access-control-policy.xml and creates an XML DOM (Document Object Model) tree. When an access control rule is encountered, it's corresponding AccessControlRulePersistenceManager acrLoad method is invoked to populate an AccessControlRule instance. As a parameter, the acrLoad method is given the XML DOM element node corresponding to the AccessControlRule. As we'll show, Cams provides various utilities for processing the XML DOM sub-tree while loading or storing your custom AccessControlRule. The AccessControlRule type is registered by use of the "<acr-type ...>" Element hierarchy.

The examples that follow show how you might write a custom AccessControlRule that can control access by day and time. Specifically, the AccessControlRule class is called BusinessHoursAcr and is available as an example in the Cams examples.acrs package.

Example 1 shows how you might declare the AccessControlRuleType for an examples:business-hours-acr within a security domain's access-control-policy.xml file and how to create an instance called business hours rule that can be referenced from other parts of the access control policy.

<access-control-policy>
	...
	<acr-lib>
		...
		<!--
			Declare the AccessControlRuleType for our example "business-hours-acr".
			(Registers this type of AccessControlRule with Cams).
		-->
		<acr-type
        name="example:business-hours-acr"
        className="examples.acrs.BusinessHoursAcr"
        desc="Control access by business hours"
		>
			<acr-persistence-manager className="examples.acrs.XmlBusinessHoursAcrPm">
				<param-list>
					<param name="debug" value="false"/>
				</param-list>
			</acr-persistence-manager>
		</acr-type>

		<!--
			Define an AccessControlRule that controls access by
			"normal business hours": Monday-Friday 8:00 AM to 5:00 PM.
		-->
		<example:business-hours-acr
			xmlns:example="http://cafesoft.com/example-business-hours-acr_1_0.dtd"
			id="business hours rule" desc="Limit access to M-F business hours">
			<example:business-hours start-hour="8" end-hour="17"/>
		</example:business-hours-acr>

		...
	</acr-lib>
</access-control-policy>
Example 1 - An example Cams access-control-policy.xml file declaring a custom AccessControlRule type and instance

Table 1 summarizes these example XML elements and attributes.

Element or Attribute Description
<acr-type> Declares a new AccessControlRuleType, which is unique type name and className.
<acr-persistence-manager> Declares the AccessControlRulePersistenceManager for the AccessControlRuleType.
<param-list> An optional list of initialization parameters that can be used to configure the AccessControlRulePersistenceManager instance.
<example:business-hours-acr ...> Declares an instance of the business-hours-acr AccessControlRule. It uses an XML namespace of example to distinguish it from intrinsic Cams access control rules or those obtained from other organizations.
xmlns:example="http://cafesoft.com/example-business-hours-acr_1_0.dtd"

Declares the acme XML namespace and specifies the file containing the Document Type Definition (DTD) for this element. Although the format for the DTD file reference is an HTTP URL, it's a unique identifier that can be resolved to a local file. Cams is setup to resolve the location of these DTD files, so for this example you'll need to create/install the DTD file at either the Cams system-wide DTD directory (which will make it available to all security domains):

${cams.home}/conf/dtd/acme-business-hours-acr_1_0.dtd

or you can install it in a security domain-specific configuration subdirectory:

${cams.security-domain.home}/dtd/example-business-hours-acr_1_0.dtd

The contents of this file declares the valid elements and attributes for this access control rule (you'll find more information on the contents of this file below).

id="business hours rule"

This case-sensitive attribute declares the unique identifier used to reference this access control rule from <permission ...> elements.

NOTE: it is also possible to instance an AccessControlRule without giving it an "id" within an <acr ...> element. This is useful if you want to limit the scope of the AccessControlRule instance.

desc="Limit access to M-F business hours" This optional attribute gives more information on the nature of the access control rule during debugging, error logging, etc.
<example:business-hours start-hour="8" end-hour="17"/>

This element is also within the example namespace and has two attributes: start-hour and end-hour, which define normal business hours for this rule instance. You might also define separate elements like this:

<example:start-hour>8</example:start-hour>
<example:end-hour>17</example:end-hour>

enabling you to get the hour values as XML element data, but in this case using element attributes is more convenient.

NOTE: The slash at the end of the element declaration ("/>") marks this element as EMPTY, which means that it cannot contain other elements.

</acme:business-hours> This element defines the end of the example:business-hours access control rule. Once this element is processed, the example XML namespace is no longer in effect (although it can be used again in subsequent elements, even for different element types, simply by using the "xmlns:example="DTD URI" attribute declaration).

Table 1 - Summary of the example:business-hours-acr XML elements

Access Control Rule Multithreading Considerations

AccessControlRule instances must be thread safe because the Cams access control system handles many access requests simultaneously. So, you'll want to be sure that you avoid the use of thread-specific instance variables within your custom AccessControlRules or that you make use of java.lang.ThreadLocal if you must associate state with specific threads.

The discussion of thread safety is beyond the scope of this document, but a number of references are given at the bottom of this document that may be helpful if you need more guidance.

Create New Access Control Rules

This section spells out the steps for creating and registering a new AccessControlRule with Cams. The example shows how you might write a custom AccessControlRule that can control access by day and time. Specifically, the AccessControlRule class is called BusinessHoursAcr and is available as an example in the Cams examples.acrs package.

Step 1 - Create an AccessControlRule class
Step 2 - Create an AccessControlRulePersistenceManager class
Step 3 - Register the AccessControlRule XML element tree with Cams
  1. Create/install an XML DTD
  2. Register the XML elements
  3. Install the compiled classes
Step 4 - Edit access-control-policy.xml to declare your AccessControlRule type
Step 5 - Edit access-control-policy.xml to create an instance of your AccessControlRule
Step 6 - Test your new AccessControlRule

Step 1 - Create an AccessControlRule class

The easiest way to create a new AccessControlRule is to extend class: com.cafesoft.cams.access.AbstractAccessControlRule, which provides default implementations for initializing an AccessControlRule and getting/setting common fields.

Example: BusinessHoursAcr.java

Although the above example does not show it, AccessControlRules have an initialize method that is passed a Config parameter which provides access to:

Step 2 - Create an AccessControlRulePersistenceManager class

An AccessControlRulePersistenceManager has methods for:

Here's an example AccessControlRulePersistenceManager for the BusinessHoursAcr.

Sample: XmlBusinessHoursAcrPm.java

Step 3 - Register the AccessControlRule XML Element tree with Cams

In this step, the new AccessControlRule XML elements are registered by creation of a new DTD file, modification of an existing DTD, and installation of classes.

Step 3a - Create/install an XML DTD

In this step, you'll need to create an XML Document Type Definition (DTD) file that describes the XML elements and attributes used to represent your custom AccessControlRule within an access-control-policy.xml file. If you havn't developed XML DTDs before, or don't have a background in formal language notations, this may look a little intimidating at first, but some provided examples and references should help you.

First, you'll need to decide where you'll install your custom DTD file: in the system-wide dtd directory or in a security domain-specific DTD directory. If you'd like your custom access control rule to be available to all security domains, put it in directory:

${cams.home}/conf/dtd

If you want to limit your custom access control rule to a specific security domain, put the DTD file in directory:

${cams.security-domain.home}/dtd

If you are not sure where the home directory for a security domain is located, you'll find a reference in the file:

${cams.home}/conf/domains/security-domain-registry.xml

Next, you'll need to create a file of the appropriate name. If the first XML element of you custom access control rule looks like this:

<example:business-hours-acr
	xmlns:example="http://cafesoft.com/example-business-hours-acr_1_0.dtd"
	id="business hours rule"
	desc="Limit access to M-F business hours">

then you'll need to create a DTD file named: example-business-hours-acr_1_0.dtd

For those of you knowledgeable about XML, Cams includes a customized EntityResolver that looks in the Cams installation directories for DTD files and returns them to the XML Parser for processing. Don't let the fully-qualified XML namespace http://cafesoft.com/example-business-hours-acr_1_0.dtd fool you. The XML parser will not attempt to load the DTD file over the network from cafesoft.com. This value is simply a unique identifier for the XML namepace used for your XML elements. For your custom access control rules, you may want to use your own company name to distinguish them from third party DTDs. For example, if your company domain name is realsecure.com, you might use: http://realsecure.com/mynamespace-my-custom-acr_1_0.dtd. The Cams EntityResolver will look for a file matching the string following the last '/' character. Whatever you place before that is purely arbitrary, but it's a good idea to use your own domain name. A standard convention for the filename itself is to use the short namespace name (in this case example), followed by the access control rule element name, followed by a version number. The version number enables you to distinguish updated XML schemas for new/improved versions of your access control rules and possibly continue supporting older versions of those access control rules.

Here's the example DTD file corresponding to the example:business-hours-acr element:

Example: example-business-hours-acr_1_0.dtd

Step 3b - Register the new XML elements

Once you've created a DTD that defines your custom AccessControlRule XML schema, you'll need to modify (or copy and modify) the DTD file for the access-control-policy.xml file itself. If your AccessControlRule is to be made available to all security domains hosted under Cams, edit file:

${cams.home}/conf/dtd/access-control-policy_1_0.dtd

If your AccessControlRule is to be deployed only a specific security domain, edit the file at:

${cams.security-domain.home}/dtd/access-control-policy_1_0.dtd

If the security domain-specific file does not exist, then copy the system-wide file to the security domain-specific directory and edit that copy. The following example shows changes that were made to support the <example:business-hours-acr ...> element.

Example: access-control-policy_1_1.dtd

Step 3c - Install the compiled classes

The following commands show how you can compile your Cams access control rule classes and deploy them to a directory where the Cams Policy Server will automatically find and load them. The examples assume that environment variable CAMS_HOME is defined and points to the "policyServer" directory within the Cams distribution.

Unix: javac -classpath .;$CAMS_HOME/lib/cams.jar:$CAMS_HOME/lib/cscore.jar -d $CAMS_HOME/classes *.java

Windows: javac -classpath .;%CAMS_HOME%\lib\cams.jar;%CAMS_HOME%\lib\cscore.jar -d %CAMS_HOME%\classes *.java

You'll need to shutdown and restart the Cams Policy Server for changes to take effect. For production use, you may want to jar your components, drop them in directory $CAMS_HOME/lib, and modify script: runcams.sh or runcams.bat to add the jar file to the Cams Policy Server's classpath.

Step 4 - Declare your AccessControlRule type

This step registers the custom AccessControlRule and AccessControlRulePersistenceManager classes within enclosing the AccessControlRuleLibrary in file access-control-policy.xml. The following example shows how to use the <acr-type ...> element and it's children to declare the example:business-hours-acr AccessControlRule type.

Example: access-control-policy.xml

Step 5 - Create an instance of your AccessControlRule

You instance your custom AccessControlRule within the AccessControlRuleLibrary and reference the newly created rule from a permission for testing within the access-control-policy.xml file.

Example: access-control-policy.xml

Step 6 - Test your new AccessControlRule

To test loading and execution of a custom AccessControlRule, start the Cams policy server and look in the trace log for the security domain that you've modified. It may be helpful to enable DEBUG level messages (see configuring the trace logger in the Cams Administrator's Guide - Security Domain Configuration) during development. At this time, no support is provided for testing AccessControlRulePeristenceManager storage and removal. Comprehensive unit testing with an API like JUnit is highly recommended.

References

For more information on XML DTDs and XML namespaces, check the following references:

  1. Java & XML, 2nd Edition Solutions to Real-World Problems, by Brett McLaughlin 2nd Edition September 2001
  2. Extensible Markup Language (XML), W3C
  3. Namespaces in XML, W3C
  4. Document Object Model (DOM), W3C
  5. Simple API for XML (SAX), SourceForge
  6. XMLFiles.com

References on Java Threads and concurrency:

  1. "Concurrent Programming in Java: Design Principals and Patterns", by Doug Lea, published by Addison-Wesley, November 1999.
  2. "Design for thread safety", by Bill Venners.
  3. "Writing efficient thread-safe classes", by Neil V. Kumar, Terway.com.
  4. "Java Threads", by Scott Oaks and Henry Wong, published by O'Reilly Associates

Back | Next | Contents