Chapter 6. Using JACC Provider

Table of Contents

6.1. Overview
6.2. Introducing JACC Protocol
6.2.1. Provider Configuration Protocol
6.2.2. Policy Configuration Protocol
6.2.3. Policy Decision and Execution Protocol
6.3. Developing JACC Provider
6.3.1. Implementing JACC Provider
6.3.2. Packaging JACC Provider
6.3.3. Default JACC Provider
6.4. Integrating JACC Providers with the JEUS Security System

This chapter describes the purpose of JACC and how to implement Custom JACC Provider to use it in the JEUS security system.

6.1. Overview

Java Authorization Contract for Containers (JACC) was first introduced in J2EE version 1.5, which is the current version.

JACC serves two basic purposes.

  • Provide a standardized SPI for EJB and Servlet authorization.

  • Ensure compatibility between existing J2SE and J2EE security models.

In short, JACC represents a standardized way of implementing an authorization provider that defines and handles authorization for EJBs and Servlets. Thus, if a JACC provider is implemented, it can be used in any JACC-compatible J2EE server.

6.2. Introducing JACC Protocol

The entire JACC specification is divided into three parts as follows:

  • Provider Protocol

  • Policy Protocol

  • Policy decision and execution protocol

Note

For more information about JACC specifications (JSR-115), refer to JACC 1.5 specification in http://java.sun.com/j2ee.

6.2.1. Provider Configuration Protocol

The JACC Provider configuration protocol describes how a JACC provider (JACC implementation) is announced and incorporated into the runtime environment of an application server. This protocol defines how JACC providers are registered with J2EE servers. In general, this process is very simple as follows:

  1. The Custom java.security.Policy class name is configured in the javax.security.jacc.policy.provider system properties. The JACC provider contains the Custom java.security.Policy class.

  2. The J2EE server reads this class name and creates a class instance, and then casts it to the java.security.Policy type.

  3. If successful, the default J2SE policy class will be replaced with the new JACC policy class by the java.security.Policy.setPolicy() method.

  4. After the completion of the previous steps, all authorization checks will be performed by the new JACC policy. The current JACC policy object can be obtained using the java.security.Policy.getPolicy() method.

Note

For more information about the JACC Provider configuration protocol, refer to JACC specifications.

6.2.2. Policy Configuration Protocol

The Policy Configuration protocol essentially defines how the security constraints defined in J2EE deployment descriptor file (ejb-jar.xml, web.xml) are to be mapped to the java.security.Permission set defined in the javax.security.jacc package. It also defines how these Permissions are to be added to the JACC provider (Custom java.security.Policy).

This helps the provider to make correct authorization decisions for EJB and Servlet modules.

Note

The Policy Configuration protocol does NOT define how to configure principal-to-role mappings. It only describes how to configure role-to-resource mappings based on the information in the standard J2EE DD file. The principal-to-role mappings are defined according to the JACC provider vendor.

Policy can be configured as follows:

  1. Specify the fully qualified class name of Custom javax.security.jacc.PolicyConfigurationFactory in the javax.security.jacc.PolicyConfigurationFactory.provider system property (“-D” property).

    The JACC provider contains Custom javax.security.jacc.PolicyConfigurationFactory class.

  2. The J2EE server reads the property and creates a class instance (PCF).

  3. Deploy the servlet and EJB modules.

  4. The deployment code parses the provided web.xml and ejb-jar.xml DD files and converts the security constraints to JACC permission instances. The permission class is included in the javax.security.jacc package. Each permission instance represents the Role-to-Resource mapping defined in the servlet and EJB.

  5. The deployment code calls the PCF.getPolicyConfiguration() method and receives an instance of the javax.security.jacc.PolicyConfiguration type.

  6. The deployment code adds the role-to-resource permissions created in step 4 to PolicyConfiguration using various PolicyConfiguration methods.

  7. After all permissions have been added, the PolicyConfiguration.commit() method is called.

When a Servlet and/or EJB module is undeployed, PolicyConfiguration.delete() method is called. This removes all the permissions of the Servlet/EJB module.

Note

For more information about the policy configuration process, refer to the JACC specifications.

6.2.3. Policy Decision and Execution Protocol

The policy decision and execution protocol describe how (EJB and Servlet) authorization decisions are to be carried out at runtime. They are applied after the requirements of the previous two protocols have been met.

Essentially, Policy decision and execution work as follows. This section uses a servlet as an example, but it also applies equally to an EJB.

  1. An HTTP request is sent to the Servlet page.

  2. The Servlet container configures some JACC context information using the javax.security.jacc.PolicyContext class.

  3. The Servlet container then constructs two JACC Web permission instances (defined in the javax.security.jacc package). These permission instances represent the permission defined for the current Servlet page.

  4. The Servlet container queries the JACC policy provider to see if the servlet requester has the two permissions mentioned in step 3. There are several ways to interpret the query.

    For example, the Policy.implies() method can be used to interpret the query. In this case, all permissions, which are checked by the java.security.ProtectionDomain that is initialized by the principal of the requester, are used as parameters.

  5. The JACC provider receives the request and determines if the requester has the permission to access the servlet page by using the following information: context information set from step 2, the permission instances created in step 3, the current principal(s), the principal-to-role mapping, and the role-to-resource mapping.

  6. If the outcome of the authorization check is positive, the Servlet container will allow access to the Servlet page. Otherwise, an authorization error page will be returned.

Note

For more information about policy decision and execution protocol, refer to the JACC specifications.

6.3. Developing JACC Provider

This section describes how to develop the Custom JACC provider and some development instructions.

6.3.1. Implementing JACC Provider

The following is a simple picture that shows the relationships between the classes that need to be implemented for your JACC provider. In the figure, the classes that need to be implemented are labeled using names starting with “MyJACC”. Any name can be chosen for these classes.

[Figure 6.1] JACC Provider Class

JACC Provider Class


The following list shows the classes that are required for a complete implementation of a JACC provider:

  • java.security.Policy

    The heart of a JACC provider implementation is usually creating a subclass of the java.security.Policy class. The class is used in JACC for authorization purposes.

    The usual way of implementing the subclass of java.security.Policy is by defining a new class, we call it MyJACCPolicy here, that extends java.security.Policy. Then, MyJACCPolicy overrides the implies() method in order to implement the policy decision and protocol that are described in "6.2.3. Policy Decision and Execution Protocol". When implementing the implies() method, both the permissions that are added using the PolicyConfiguration interface and the principal-to-role mappings must be considered in order to interpret an authorization query.

    MyJACCPolicy must provide a public constructor without parameters, so that the application server can easily create a class instance.

  • javax.security.jacc.PolicyConfigurationFactory

    In order to satisfy the Policy configuration protocol, the application server must be able to add permission instances to JACC java.security.Policy. This is accomplished using the javax.security.jacc.PolicyConfiguration interface. The abstract class, javax.security.jacc.PolicyConfigurationFactory, is used to create the PolicyConfiguration instance.

    Thus, in order to create a complete JACC provider, you must implement the getPolicyConfiguration() method in the javax.security.jacc.PolicyConfigurationFactory class. This means that you must create a new subclass of the javax.security.jacc.PolicyConfigurationFactory class. Here, we call the new class MyJACCPolicyConfigurationFactory. MyJACCPolicyConfigurationFactory must be a concrete class with a public no-argument constructor, so that it can be easily instantiated by the application server.

    The MyJACCPolicyConfigurationFactory must provide a public no-argument constructor to enable the J2EE server to easily create instances of the class.

  • javax.security.jacc.PolicyConfiguration

    In order to implement the Policy configuration protocol, the application server must be able to add permission instances to the JACC java.security.Policy implementation. This is accomplished through an instance of the javax.security.jacc.PolicyConfiguration interface. An instance of this interface is created through the abstract class, javax.security.jacc.PolicyConfigurationFactory, as already mentioned.

    Implementing the javax.security.jacc.PolicyConfiguration interface is thus a requirement to complete a JACC provider. We will call our implementation class MyJACCPolicyConfiguration.

    javax.security.jacc.PolicyConfigurationFactory implementation (MyJACCPolicy ConfigurationFactory) should always return an instance of the MyJACCPolicyConfiguration class.

Note

This section briefly explains how to implement each of the classes. For more information about how to implement the javax.security.jacc.PolicyConfiguration class, refer to the Policy Configuration Protocol of the JACC specification, and the J2EE Javadoc for each class.

6.3.2. Packaging JACC Provider

In general, the JACC Provider and the supporting classes referenced by the JACC provider should be packaged together into a JAR file and be delivered, in a JAR format, to the target application server. We will call the JAR file, “MyJACCProvider.jar”.

The path of the JAR file for the JACC provider must be included in the application server path. If needed, certain system properties can be configured, but the procedure for this varies slightly for different application servers. How to configure this for JEUS will be explained in "6.4. Integrating JACC Providers with the JEUS Security System".

6.3.3. Default JACC Provider

The JEUS security system provides a very simple default JACC provider. In general, it is strongly discouraged to use this default provider as it was mainly developed for test purposes. Instead, the default standard authorization provider described in the earlier chapter is recommended for use.

However, if you wish to use another JACC provider, you must create your own JACC JAR archive and include the JACC provider file in it since there is no support for commercial products.

6.4. Integrating JACC Providers with the JEUS Security System

This section describes how to integrate JACC providers with the JEUS security system.

The process to integrate the JEUS security system with a JACC Provider is as follows.

  1. Implement a Principal-to-Role Mapper

    The JACC interface does not contain any implementation related to principal-to-role mapping, but only for role-to-resource mapping. The user must implement a separate JEUS-specific interface to implement the mapping, and JEUS provides the isjeus.security.impl.aznrep.JACCPrincipalRoleMapper interface for this purpose. This interface contains a single method, that needs to be implemented, called addPrincipalRoleMapping(PermissionMap map, String policyId). This method adds the principal-to-role mapping to PolicyConfiguration, which is represented by the policyId.

    Note

    Note that principal-to-role mappings have application scope in J2EE. This is because all the principal-to-role mappings in an application are merged into a single map. Refer to the API documentation for more information about the PermissionMap class and about the add() method, that is used in merging PermissionMap instances.

    The implementation of the JACCPrincipalRoleMapper interface must provide a public no-argument constructor, and it must be added to the JAR file of the JACC Provider. For more information on this, refer to References and Javadoc.

    The process of the JACCPrincipalRoleMapper interface creating the principal-to-role mapping is as follows:

    1. The class name that implements the jeus.security.jacc.principalRoleMapper class is configured to the system property, jeus.security.jacc.principalRoleMapper.

    2. The class that implements the jeus.security.impl.aznrep.JACCAuthorizationRepositoryService class reads this property to create an instance by calling the Class.forName(mapperClassname).newInstance() method.

    3. Then the addPrincipalRoleMapping() method of the instance is called to create and add the principal-to-role mappings, that are defined in the JEUS DD file.

  2. Setting the Security Configuration File

    The JEUS security system uses two adapter classes to connect JEUS native authorization API with the JACC authorization API.

    The roles of the two adapter classes are as follows:

    • jeus.security.impl.azn.JACCAuthorizationService

      implements the container part of the Policy Decision and Execution protocol by invoking the java.security.Policy.getPolicy().implies() method to check for authorization.

    • jeus.security.impl.aznrep.JACCAuthorizationRepositoryService

      implements the Policy Configuration protocol by allowing the container-generated jeus.security.base.Policy instance to be added to the PolicyConfiguration instance, which is a configuration component of the JACC provider.

    In order to enable JACC, both of these security Services must be configured in the domain service definition of the domain.xml file.

    [Example 6.1] JACC Security Configuration File: <<domain.xml>>

    <?xml version="1.0"?> ...
                <security-domains>
                <default-application-domain>JACC_DOMAIN</default-application-domain>
                ... <security-domain> <name>JACC_DOMAIN</name>
                <authorization> <jacc-service/> </authorization>
                </security-domain> . . . </security-domains>
                


  3. Adding the JACC Provider JAR file to the System Path

    To add the JACC provider JAR file to the system path, simply place the JAR file in the following directory.

    JEUS_HOME/lib/system
  4. Setting Java System Properties

    The JACC protocol and JEUS specifies three Java system properties to enable the J2EE server to detect the presence of the JACC provider. These properties are as follows:

    • javax.security.jacc.policy.provider

      The name of the class that represents the JACC Provider, and implements java.security.Policy.

    • javax.security.jacc.PolicyConfigurationFactory.provider

      The name of the class that implements PolicyConfigurationFactory that creates and loads PolicyConfiguration instances.

    • jeus.security.jacc.principalRoleMapper

      The name of the class that implements the jeus.security.impl.aznrep.JACCPrincipalRoleMapper interface, and creates the principal-to-role mapping from JEUS DD file.

    The previous three system properties must be configured in the <jvm-option> element of domain.xml.

    [Example 6.2] Java System Property Configuration for JACC <<domain.xml>>

    <?xml version="1.0"?>
                <domain xmlns=“http://www.tmaxsoft.com/xml/ns/jeus”>
                <servers> <server> <name>server1</name>
                <!-- server JVM option --> 
                <jvm-config> . . . <jvm-option>
                -Djavax.security.jacc.policy.provider= myprovider.MyJACCPolicy
                </jvm-option> <jvm-option>
                -Djavax.security.jacc.PolicyConfigurationFactory.provider=
                myprovider.MyJACCPolicyConfigurationFactory </jvm-option>
                <jvm-option> -Djeus.security.jacc.principalRoleMapper=
                myprovider.MyJACCPrincipalToRoleMapper </jvm-option>
                </jvm-config> . . .


Default JACC Provider Class Name

As already mentioned, the default class names for JACC provider are as follows:

ClassificationClass Name
Policyjeus.security.impl.jacc.JACCPolicyWrapper
PolicyConfigurationFactoryjeus.security.impl.jacc.JACCPolicyConfigurationFactoryImpl
JACCPrincipalRoleMapperjeus.security.impl.jacc.JACCDefaultPrincipalRoleMapper

These classes are packaged and placed in the following location.

JEUS_HOME/lib/system/jeus.jar