OpenJACC

SourceForge.net Logo

Introduction

OpenJACC is an implementation of the Java Authorization Contract for Containers. OpenJACC will allow fine-grained declarative access control of J2EE applications. OpenJACC can be deployed in any J2EE Server which supports the JACC interface; in particular OpenJACC can be deployed in any J2EE 1.4 compliant application server.

The J2EE Servlet and EJB containers serve as an authorization boundary between callers and container-hosted components. When a container receives a request for a component, it determines if the caller has been granted permission to perform the request on the component. Containers which support the JACC API can delegate the authorization decision to a JACC Provider, e.g. OpenJACC.

Currently, no open-source or commercial J2EE Application Server provides method-level context-dependent declarative authorization out-of-the-box. Such authorization features are only supported by commercial security products which use application-server proprietary APIs. OpenJACC will provide such fine-grained declarative authorization using standard APIs.

OpenJACC will support the definition of fine-grained authorization policies in xml configuration files. Authorization policies will be defined using an expression language. Using the Expression Language, complex boolean expressions can be constructed which utilize, for example, ejb method parameters. In the future, we hope to provide for authorization policies using XACML, as well as other scripting languages, e.g. ECMA Script. Apache JEXL will be supported first, as it is fairly easy to use.

OpenJACC will first provide support for WebLogic Server 8.1 using the Authorization features of theWebLogic Server Security Service Provider Interface. Although this interface is not JACC Compliant, it is very similar to the JACC specification. WLS 8.1 will be supported first, as it is production-grade and widely deployed.

Development of a JACC Provider will begin in earnest as soon as WebLogic Server 9.0 is GA. WLS 9.0 will be J2EE 1.4 compliant and implement the Container side of the JACC contract.

Rule-Based Access Control

I've often encountered situations where powerful declarative access control was desired; that's what lead me to the development of OpenJACC. All application servers allow declarative access control based on user group membership. Access to resources, e.g. EJB Functions, can be limited users who belong to roles. The question, does 'the caller belong to the role' usually boils down to group membership.

This type of declarative access control is very limited, and leads to security logic being implemented in the application. The goal of OpenJACC is to enrich declarative access control. Some simple examples include:

Execution context

In the next example, users are granted access, if they are a member of the HeavyTrader role and the second argument to the function is greater than 200, or if they are a member of the statelessSessionTester role (defined in the previous example).

 (roles.contains('HeavyTrader') && args[1] > 200) ||
            roles.contains('statelessSessionTester')

The expressions above are written in JEXL, a simple expression language. The execution context contains the following:

All method arguments are placed in a Vector of objects. Note that, the obects may be very complex; they can be navigated using simple expression language semantics. Say, for example, that the argument was a Loan object, and the amount was an attribute (Loan has a getPrincipal():int function). We could instead write:

 args[0].loan.principal<=10000 || subject.isUserInGroup('Manager') 

This says that if the loan's principal is more than 10000, the user has to be a manager to approve it.

The Caller's Subject is available (actually, the subject is 'wrapped' making it easier to work with in the expression language). The subject contains the Principals of the caller which includes the groups the caller belongs to.

Say, for example, a test users whose name starts with 'test' are allowed to execute certain functionality.

 subject.username.startsWith("test")

Group Intersections

Typically, roles can be mapped to a number of groups, i.e. they are the union of all members of all groups. With OpenJACC, it's very easy to compute role membership based on Group intersection:
 subject.isUserInGroup('Trader')
            && subject.isUserInGroup('HeavyUsers')
In the example above, the user is a member of the role, if he is a member of both the Trader and the HeavyUsers groups.

User Profile

Often, it's necessary to make access control decisions based on some attributes of a user:
 (args[0].loan<=10000 &&
            user.personal.title='Controller' ) && subject.principals['Manager'] !=
            null
The user object contains multiple 'property sets'. Each property set is a scope for multiple properties. Each property sets is typically pulled from a single source, e.g. LDAP or a Database. (not implemented yet)

Deploying OpenJACC in your server

EJB Configuration

Configure EJB Security

Define Security roles and method permissions in the ejb-jar.xml deployment descriptor. Mark the roles as externally-defined in the weblogic-ejb-jar.xml deployment descriptor. Note that the WLS Docs are incorrect: the externally-defined element has no value (not true/false). See <OPENJACC_HOME>/src/org/openjacc/test/ejb/statelessSession/META-INF/ejb-jar.xml for an example.

Setup login.config

Java ejb clients should use JAAS. To use JAAS in WLS Java Clients, the JRE must be configured to use the WLS Login Module (see Using JAAS Authentication in Java Clients). To do this, copy <OPENJACC_HOME>src/org/openjacc/test/.java.login.config to your 'user.home', e.g., for user 'vijay' "c:\Documents and Settings\vijay" or in unix, to your home directory.

Deploy EJB

Do not use WLS autodeploy features (i.e. copying the jar into the applications directory under the domain). WLS does not perform access control checks for auto-deployed applications. Deploy the EJB from some other directory, using the WLS Console.

WLS Configuration

Modify classpath

Modify your start script, and put the following in your WLS classpath:

Set alternate mbeantypes directory

Add the following option to WLS:
            -Dweblogic.alternateTypesDirectory=<OPENJACC_HOME>/out/mbeantypes
        
This directory contains the OpenJACC WLS SSPI Role Mapper Provider Jar.

Set OpenJACC Policy Root

OpenJACC locates policies in a specified directory. By default, it looks in the working directory. The policy for an application is the <Policy Root>/<Application Name>.xml. Set the following option.
            -Dorg.openjacc.policy=<Policy Root>
        
Refer to <OPENJACC_HOME>/src/org/openjacc/test/policy for example policies.

Configure the OpenJACC Role Mapping Provider

Start WLS, and add the OpenJACC Role Mapper. SeeConfiguring a WebLogic Role Mapping Provider.

Write Your Policy

Now you should be ready to go. Write your policy, place in the policy root, and give it a swing.

Building

Modify <OPENJACC_HOME>/build.properties

Set the bea.home and wl.home properties to match your WebLogic installation.

Open a command prompt or shell

Set up Ant and JDK environment

The easiest way to do this is to call <WEBLOGIC_HOME>/common/bin/commEnv.cmd or commEnv.sh

Add JUnit to the classpath

Add <OPENJACC_HOME>/lib/junit.jar to the classpath.

Run ant

cd to the <OPENJACC_HOME> directory, and execute "ant all". This will build all

Running the examples

OpenJACC is shipped with a WLS Domain, a couple test enterprise apps and corresponding policies. If you're interested, start with the sample policies, and then look at the JUnit Test Cases.

Setup the environment, build

See building, and follow the instructions there for setting up the environment. Run "ant all" to build all source.

Setup the WLS Domain

WLS scripts and the configuraton are generated from templates. Call "ant wls.setup" to setup the domain.

Run the unit tests

Call "ant test.engine test.wls" to run all unit tests. test.engine runs simple standalone tests against the OpenJACC engine. test.wls starts wls, runs test.ejb, and stops wls.

Status

As you can see, first stab, just a prototype, feedback and suggestions very welcome: Vijay Garla. What we'll add next, in no particular order, is:

Release Notes

This has been tested with WLS version 8.1 service pack 4 on Windows XP and SuSE Linux 9.2. This should work on any supported WLS 8.1 platform. This document was last updated on 2005-04-11.