Skip Headers
Oracle® Containers for J2EE Security Guide
10g (10.1.3.5.0)

Part Number E13977-01
Go to Documentation Home
Home
Go to Book List
Book List
Go to Table of Contents
Contents
Go to Index
Index
Go to Feedback page
Contact Us

Go to previous page
Previous
Go to next page
Next
View PDF

5 Authorization in OC4J

Chapter 2, "Java Platform Security" provided an overview of three major Java security models: J2EE role-based security, Java 2 code-based security, and JAAS subject-based security.

This chapter shows how to use the authorization features with each of these models. They can be used individually or in combinations. At the end of the chapter there is discussion of how to choose between security models.

The following topics are covered:

Java 2 Security and Code-Based Policy Management

This section discusses security managers and policy files for Java 2 (code-based) security, covering the following topics:

Specifying a Java 2 Security Manager and Policy File

For Java 2 (code-based) security policies to be enforced by OC4J and the underlying JDK, a security manager (java.lang.SecurityManager instance) must be enabled. This may affect, for example, access to class loaders, access to JDK resources, execution of JDK APIs, or execution of JAAS APIs (such as the ability for the Subject.doAs() or Subject.doAsPrivileged() method to be executed). With a security manager enabled, the policies specified in the Java 2 policy file determine the resources that executing code can access.

You can specify a security manager in either of the following ways:

  • Call the static setSecurityManager(SecurityManager) method of the java.lang.System class to specify any desired security manager.

  • Use the system property java.security.manager when starting OC4J, either with no setting to use the default security manager, or with a setting that indicates a desired security manager.

The following example starts OC4J with the default security manager:

% java -Djava.security.manager ... -jar oc4j.jar

The following example specifies a security manager:

% java -Djava.security.manager=com.abc.MySecurityManager ... -jar oc4j.jar

Notes:

  • Using a security manager is not typically necessary in OC4J. Within an Oracle Application Server installation, OC4J instances run by default with no security manager. If you choose to install a security manager, there may be significant performance impact. If you use a custom security manager, ensure that it does not interfere with OC4J functions.

  • Assuming you use the default implementation of AccessController (provided with the Sun JDK), a call to AccessController.checkPermission(), discussed in "Using the checkPermission() Method", enforces Java 2 security policy for your application regardless of whether a security manager is enabled.

The permissions granted to particular classes by the default security manager are determined by reading a policy file. The default policy file is supplied as part of the J2SE. You can specify any desired policy file by setting the system property java.security.policy to the full path of the desired file. The following example starts OC4J with the default security manager and the policy file that is supplied with OC4J:

% java -Doracle.home=$ORACLE_HOME -Djava.security.manager \
       -Djava.security.policy=$ORACLE_HOME/j2ee/home/config/java2.policy \
       -jar oc4j.jar

Notes:

  • Be aware that this java2.policy file includes permissions that are required for OC4J to run with a security manager. If you use a different policy file, make sure the same permissions are included in that file.

  • A .policy file is for Java 2 (code-based) policies only. With the OracleAS JAAS Provider, JAAS (subject-based) policies are declared within the <jazn-policy> element of the system-jazn-data.xml file, or in Oracle Internet Directory if you are using the Oracle Identity Management security provider, as discussed in "OracleAS JAAS Provider Policy Configuration".

Using PrintingSecurityManager to Determine Required Java 2 Permissions

To assist you in identifying all the required permissions for an application running on OC4J, Oracle provides a custom security manager, PrintingSecurityManager, that does not throw security exceptions. Instead, it prints a message specifying what exceptions the default security manager would have thrown. PrintingSecurityManager also generates the policy grants that would avoid the security exceptions.

Run PrintingSecurityManager as in the following example, assuming you run OC4J from ORACLE_HOME/j2ee/home:

% java -Xbootclasspath/p:lib/oc4j-psm.jar -Doracle.home=$ORACLE_HOME \
       -Djava.security.manager=oracle.oc4j.security.PrintingSecurityManager \
       -Djava.security.policy=$ORACLE_HOME/j2ee/home/config/java2.policy \
       -jar oc4j.jar

(-Xbootclasspath puts PrintingSecurityManager into the boot classpath, where it runs with all permissions.)

PrintingSecurityManager generates output that lists the following:

  • Which codesources require which permissions

  • Policy grants that you can copy and paste into the policy file

By default, these outputs go to System.out, but you can specify output files through the following system properties. The first is for messages about missing permissions; the second is for policy grants:

-Doracle.oc4j.security.manager.printing.file=filenamepath
-Doracle.oc4j.security.manager.printing.generated.grants.file=filenamepath

Note:

PrintingSecurityManager is not tied to OC4J, so you can alternatively use it outside of OC4J.

Creating or Updating a Java 2 Policy File

A Java 2 policy file grants permissions to trusted code or applications, allowing them appropriate access privileges to execute properly in your environment.

A preconfigured Java 2 policy file, java2.policy, is provided in ORACLE_HOME/j2ee/home/config. You can modify this file if desired, or create and specify an alternative policy file. Be aware, however, that the java2.policy file supplied by Oracle includes permissions that are required for OC4J to run with a security manager. If you use a different policy file, make sure the same permissions are included in that file.

The following policy file sample grants all permissions, such as opening system files and opening sockets or ports, to the trusted jazn.jar (the OracleAS JAAS Provider Admintool):

/* grant the JAAS library AllPermission */ 
grant codebase "file:${oracle.home}/j2ee/home/jazn.jar" { 
    permission java.security.AllPermission; 
}; 

Similarly, the following example grants all permissions to wssecurity.jar (for Web services security functions):

/* grant the WSSecurity AllPermission */ 
grant codebase "file:${oracle.home}/webservices/lib/wssecurity.jar" { 
    permission java.security.AllPermission; 
}; 

The following example grants specific permissions to all applications running in the ORACLE_HOME/appdemo directory:

/* Assuming you are running your application demo in $ORACLE_HOME/appdemo/, */ 
/* Grant JAAS permissions to the demo to run JAAS APIs*/ 
grant codebase "file:/${oracle.home}/appdemo/-" {  
   permission oracle.security.jazn.JAZNPermission "getPolicy"; 
   permission oracle.security.jazn.JAZNPermission "getRealmManager"; 
   permission oracle.security.jazn.policy.AdminPermission;
}

You can grant additional permissions for your application code or for classes generated by OC4J, as necessary, by manually creating additional entries in the .policy file. (There is currently no tool for this.) The required permissions will depend on the details of your application, and the required codebase will depend on the details of your installation.

Note:

Note the use of "${oracle.home}" to specify the location of ORACLE_HOME. This is an environment variable that is set appropriately by default.

See Also:

Authorization APIs, JAAS Mode, and JACC in the OC4J Environment

This section discusses the following authorization features in OC4J:

JAAS Authorization and OracleAS JAAS Provider JAAS Mode

OracleAS JAAS Provider allows any protected resource to be modeled using Java permissions. The Java permission model (and associated java.security.Permission class) is extensible and allows a flexible way to define fine-grained access control.

OracleAS JAAS Provider builds upon the J2SE standard, using standard APIs to support the following features related to fine-grained authorization:

  • JAAS mode, which is related to standard Subject.doAs() and Subject.doAsPrivileged() functionality for either Web applications or EJBs

  • OracleAS JAAS Provider realm and policy API features

  • Features for granting permissions

  • Features for checking permissions

Note:

APIs documented here can be used with either system-jazn-data.xml or Oracle Internet Directory as the policy repository.

See Also:

Introduction to JAAS Mode

OC4J 10.1.3.x implementations provide a fine-grained authorization feature called JAAS mode, which is related to standard functionality of the Subject class static methods doAs() and doAsPrivileged(), discussed in "JAAS Authorization: Subject Methods doAs() and doAsPrivileged()".

These methods are used with your application according to your JAAS mode setting. Set JAAS mode in the jaas-mode attribute of the <jazn> element in the orion-application.xml file of your application. JAAS mode determines doAs() or doAsPrivileged() usage as follows:

  • With the setting jaas-mode="doAs", application modules (Web modules and EJBs) are executed by OC4J within a Subject.doAs() block.

    This mode is useful if you want code-based security together with subject-based security.

  • With the setting jaas-mode="doAsPrivileged", application modules are executed within a Subject.doAsPrivileged() block, using a null access control context.

    This mode is useful if you want subject-based security only.

  • With the setting jaas-mode="null" (default), modules are executed under neither method.

    This mode is useful if you want code-based security only.

Because jaas-mode is set in the application-level orion-application.xml file, it will affect any Web module or EJB in the application.

Important:

  • Set jaas-mode in orion-application.xml only, not in jazn.xml.

  • If you switch from the file-based provider to Oracle Identity Management at any time for any application through Application Server Control, the <jazn> element in orion-application.xml for the application is replaced with the following. Any previous <jazn> settings would be lost and would have to be redone.

    <jazn provider="LDAP" />
    

Note:

JAAS mode replaces runas-mode and doasprivileged-mode settings from earlier releases, in the <jazn-web-app> element of orion-application.xml or orion-web.xml.

These settings are deprecated in OC4J 10.1.3.x implementations, but still supported for backward compatibility.

The setting jaas-mode="null" is equivalent to runas-mode="false"; jaas-mode="doas" is equivalent to runas-mode="true" with doasprivileged-mode="false"; jaas-mode="doAsPrivileged" is equivalent to runas-mode="true" with doasprivileged-mode="true".

See Also:

OracleAS JAAS Provider Realm and Policy APIs

This section discusses OracleAS JAAS Provider classes and methods related to JAAS authorization.

An instance of the oracle.security.jazn.JAZNConfig class represents a configuration of the <jazn> element. This class includes the following methods:

  • JAZNConfig getJAZNConfig()

    This static method of the JAZNConfig class returns a JAZNConfig instance.

  • RealmManager getRealmManager()

    This instance method of the JAZNConfig class returns a RealmManager instance, which is used to manage realms.

The oracle.security.jazn.realm.RealmManager class includes the following instance method:

  • Realm getRealm(String)

    This method returns a realm object for the specified realm name.

An instance of the oracle.security.jazn.realm.Realm class provides access to the store of users and roles for the particular realm. In the realm package, user management is defined by the UserManager interface and role management is defined by the RoleManager interface. The Realm class includes the following instance methods:

  • UserManager getUserManager()

    This method returns a UserManager instance, which you can use to manage users in this realm.

  • RoleManager getRoleManager()

    This method returns a RoleManager instance, which you can use to manage roles in this realm.

Use an oracle.security.jazn.realm.UserManager instance to manage (add, retrieve, or remove) users in the realm. This interface includes the following method:

  • RealmUser getUser(String)

    This method returns a user object, for the specified name of a user in the realm.

See Also:

OracleAS JAAS Provider APIs for Granting or Revoking Permissions

The JAZNConfig class, mentioned in the preceding section, also has the following method:

  • JAZNPolicy getPolicy()

    This method returns an oracle.security.jazn.policy.JAZNPolicy instance, which represents the repository of JAAS (subject-based) authorization policies.

The JAZNPolicy interface includes the following methods:

  • void grant(Grantee, Permission)

    This method grants the specified permission to the specified grantee, taking as input an oracle.security.jazn.policy.Grantee instance and a java.security.Permission instance.

  • void revoke(Grantee, Permission)

    This method revokes the specified permission for the specified grantee.

  • boolean hasPermission(Grantee, Permission)

    This method determines whether the specified grantee has the specified permission.

The Grantee class includes a constructor that takes a Principal instance as input:

  • new Grantee(Principal)

Table 5-1 summarizes permission classes supplied by Oracle.

Note:

Features to grant permissions to a role replace functionality in the deprecated com.evermind.security.Group class.

See Also:

  • For information about these classes, the OracleAS JAAS Provider Javadoc: Oracle Containers for J2EE Security Java API Reference

Table 5-1 OracleAS JAAS Provider Permission Classes

Permission Part of Package Description

AdminPermission

oracle.security.jazn.policy

Represents the right to administer a permission (that is, grant or revoke another user's permission assignment).

RoleAdminPermission

oracle.security.jazn.policy

The grantee of this permission is granted the right to further grant/revoke the target role.

JAZNPermission

oracle.security.jazn

For authorization permissions. JAZNPermission contains a name (also called a target name), but no actions list; you either have or do not have the named permission.

RealmPermission

oracle.security.jazn.realm

Represents permission actions for a realm (such as createRealm and dropRealm). Extends java.security.Permission, and is used like any regular Java permission. A RealmPermission instance associates a realm name (target name) with a list of actions.

RMIPermission

com.evermind.server.rmi

This permission is required for access to EJBs over the ORMI protocol. Typical usage is RMIPermission login (such as from the OracleAS JAAS Provider Admintool).


You can construct instances of these permission classes as follows:

  • new AdminPermission(String)

  • new AdminPermission(Permission)

    The AdminPermission constructor takes an encoded permission string or a java.security.Permission instance.

  • new RoleAdminPermission(String)

  • new RoleAdminPermission(RealmRole)

    The RoleAdminPermission constructor takes one of the following:

    • A string indicating the name of the role whose administrative permission is to be granted, of the form realmname/rolename. Specifying just "*" will match all roles in the system; specifying "realm/*" will match all roles in the realm.

    • An oracle.security.jazn.realm.RealmRole instance, which is an instance of a class that implements the RealmRole interface, representing a role associated with a particular realm.

  • new JAZNPermission(String)

    The JAZNPermission constructor takes a symbolic name of the permission, such as "getRealmManager", "getPolicy", "getProperty.propertyname", and so on.

  • new RealmPermission(String realm, String actions)

    The RealmPermission constructor takes a string for the name of the realm, and a string consisting of a comma-delimited list of the actions applicable to the realm.

  • new RMIPermission(String param, String actions)

    The RMIPermission constructor takes a string for the RMIPermission parameter (login, for example) and a string consisting of a comma-delimited list of applicable actions.

You can also construct instances of standard permission classes, as needed:

  • new Permission(String permname)

    The java.security.Permission constructor takes a string to specify the name of the permission.

  • new BasicPermission(String permname)

    The java.security.BasicPermission constructor takes a string to specify the name of the permission.

  • new FilePermission(String path, String actions)

    The java.security.FilePermission constructor takes one string to specify the path of the file in question, and another string that is a comma-delimited list of permissible actions. Supported actions are "read", "write", "execute", and "delete".

  • new AllPermission()

    An instance of the java.security.AllPermission class is a permission that represents all other permissions. Its constructor takes no parameters.

Important:

AllPermission should be used with caution, and only when necessary.

Note:

While there are standard mechanisms for checking permissions (as described in the next section), JAAS does not provide standard mechanisms for managing users and granting permissions. This is why the classes and methods described in this section are Oracle-specific.

APIs for Checking Permissions

Access control, such as checking permissions, was introduced in "Java 2 Authorization: Security Managers and Access Controllers". Any of the following APIs may be involved in retrieving and checking permissions.

The java.security.AccessController class includes the following methods:

  • AccessControlContext getContext()

    This method examines the current calling context, which includes the inherited access control context of the current thread, and represents the context as a java.security.AccessControlContext instance.

  • void checkPermission(Permission)

    Given a java.security.Permission instance, this static method checks whether the access request indicated by the permission should be allowed, and throws an AccessControlException if it should be denied. This method uses the default access control context.

    Note that this method enables you to check against Java 2 policy (as applicable) without a security manager enabled.

The java.security.AccessControlContext class includes the following method:

  • void checkPermission(Permission)

    This has the same functionality as the AccessController.checkPermission() method, but is called on a particular AccessControlContext instance to use that access control context. (You can construct an AccessControlContext instance from an array of ProtectionDomain instances.)

    Note that this method enables you to check against Java 2 policy (as applicable) without a security manager enabled.

The java.lang.SecurityManager class includes the following method:

  • void checkPermission(Permission)

    This has the same functionality as the checkPermission() methods of the AccessController and AccessControlContext classes, but is used with a security manager in place, is called against the security manager instance, and throws a SecurityException if access should be denied.

The javax.security.auth.Subject class includes the following method:

  • Subject getSubject(AccessControlContext)

    This static method returns the subject that is associated with the specified access control context. You can specify the default access control context as follows:

    mysubject = Subject.getSubject(AccessController.getContext());
    

The abstract class javax.security.auth.Policy includes the following methods:

  • Policy getPolicy()

    This static method returns a Policy instance.

  • PermissionCollection getPermissions(Subject, CodeSource)

    This method, given a javax.security.auth.Subject instance or a java.security.CodeSource instance or both (inputs can be null), returns a java.security.PermissionCollection instance that indicates the set of permissions allowed. The codesource field can be null.

The PermissionCollection class includes the following method:

  • boolean implies(Permission)

    This abstract method indicates whether the specified permission is implied by the set of permissions in the permission collection. For example, if the permission collection consists of permissions of a subject, this method tells you if the subject has the specified permission, such as in the following example:

    jaaspolicy = javax.security.auth.Policy.getPolicy();
    jaaspolicy.getPermissions(mysubject,null).implies(perm);
    

Note:

The javax.security.auth.Policy class is deprecated in JDK 1.4 but fully supported in OC4J 10.1.3.x implementations and still supported by the Sun Microsystems JDK and J2SE. As of this release, OC4J itself does not support the java.security.Policy class.

See Also:

Setting a Subject Into the OC4J Container

JAAS based authentication is not well integrated with Java EE. Typically JAAS authentication requires the use of a login module. However, a login module (including custom login modules) do not assert the Subject into the container. This behavior causes applications to not use the authenticating subject. To solve this problem OC4J provides an API that allows a Subject to be asserted into the OC4J container that can be used in place of container managed security (declarative security).The API is located in the oracle.oc4j.security package and is used as follows:

Security.setSubject(Subject subject, Longevity longevity);

The setSubject method asserts the Subject identity into the container for this request and all further requests associated with the Web container if applicable. If the current application context does not have a Web component, then only the current application server thread context will make use of the Subject and upon returning to the pool it will be cleared. This API is only relevant for server-side execution and not for application client-side code.

  • subject – the identity to assert into the container

  • longevity – the duration for which the identity assertion should be held. This can be Longevity.REQUEST or Longevity.SESSION.

Implementation of Java Authorization Contract for Containers

OC4J 10.1.3.x implementations support the Java Authorization Contract for Containers (JACC), as specified in JSR-115. This is a contract between containers and authorization service providers, allowing authorization to be decoupled from the container. OC4J authorization functionality is delegated to a standard JACC provider.

Note that as a result of the JACC contract, J2EE security constraints are translated into Java 2 permissions, so that the J2EE security model fully leverages the J2SE security model. Yet JACC still fully preserves the existing J2EE declarative security model as well as the J2EE security API. Essentially, you can enable JACC to use an extended version of J2EE authorization, using the same configuration and code for authorization in your application.

JACC is typically invisible to a developer; it is more of a deployment-time consideration.

The contract defined in JSR-115 interacts with an application server container, deployment tools, and policy provider, and is divided into the following subcontracts:

  • Provider configuration subcontract

  • Policy configuration subcontract

  • Policy decision and enforcement subcontract

JACC provides new java.security.Permission class implementations that adhere to the J2EE authorization model. Under JACC, access decisions by the container are made according to operations on instances of these Permission classes. JACC defines the ways that policy providers make use of the new permission classes to address requirements of the J2EE authorization model, as follows:

  • Defining roles as collections of permissions

  • Granting the permissions of a role to a principal

  • Determining whether a principal has been granted the permissions of a role

OracleAS JAAS Provider Policy Management

There is not a set standard for subject-based policy management; the implementation is left up to each vendor. This section discusses how to use OracleAS JAAS Provider features for subject-based policy management—granting permissions, the resulting configuration, checking permissions, and (where necessary) explicitly specifying the OracleAS JAAS Provider policy provider:

See Also:

Granting Permissions through the OracleAS JAAS Provider Admintool

With either system-jazn-data.xml or Oracle Internet Directory as the policy repository, you can use the OracleAS JAAS Provider Admintool to grant, revoke, or list permissions—using the grantperm, revokeperm, or listperm command, respectively. (An alternative, for runtime, is to use APIs discussed in the next section, "Using OracleAS JAAS Provider Policy Management APIs".) Complete syntax for these commands is documented in "Granting and Revoking Permissions" and "Listing Permissions".

You can grant permissions to a user (through the grantperm -user option), to a role (through the -role option), or to a principal.

For example, to grant RMI permission "login" to the role developers in the realm myrealm:

% java -jar jazn.jar -grantperm myrealm -role developers \
     com.evermind.server.rmi.RMIPermission login

(RMI permission "login" is a permission you must often grant to allow EJB/RMI access.)

To grant this same permission to the user JDOE_ENDUSER:

% java -jar jazn.jar -grantperm myrealm -user JDOE_ENDUSER \
     com.evermind.server.rmi.RMIPermission login

To grant this permission to the LDAP principal hobbes (when using an external LDAP provider):

% java -jar jazn.jar -grantperm oracle.security.jazn.realm.LDAPPrincipal hobbes \
       com.evermind.server.rmi.RMIPermission login 

To grant FilePermission for a file sample.txt for actions "read, write" to user martha in realm foo:

% java -jar jazn.jar -grantperm foo -user martha java.io.FilePermission
     sample.txt read,write

Resulting configuration from the grantperm command is discussed in "OracleAS JAAS Provider Policy Configuration".

See Also:

Using OracleAS JAAS Provider Policy Management APIs

With either system-jazn-data.xml or Oracle Internet Directory as the policy repository, you can use OracleAS JAAS Provider policy management APIs to grant or revoke permissions. (An alternative, for nonruntime, is to use OracleAS JAAS Provider Admintool commands discussed in the preceding section, "Granting Permissions through the OracleAS JAAS Provider Admintool".) In this example, the doGet() method shown in "Using J2EE Authorization APIs" is expanded to use the OracleAS JAAS Provider policy management API to grant file permissions to a user.

public void doGet(HttpServletRequest request, HttpServletResponse response)
       throws ServletException, IOException {
   ServletOutputStream out = response.getOutputStream();
 
   response.setContentType("text/html");
   out.println("<HTML><BODY bgcolor=\"#FFFFFF\">");
   out.println("Time stamp: " + new Date().toString());
   out.println("request.isUserInRole('ar_developers') = " +
                request.isUserInRole("ar_developers") + "<br>");
   try { 
   //Grant Permissions to a user developer

   //get JAZNConfiguration related info
      JAZNConfig jc = JAZNConfig.getJAZNConfig();

   //create a Grantee for "developer"
      RealmManager realmmgr = jc.getRealmManager();
      Realm realm = realmMgr.getRealm("jazn.com");
      UserManager userMgr = realm.getUserManager();
      final RealmUser user = userMgr.getUser("developer");

   //grant developer file permission
      JAZNPolicy policy = jc.getPolicy();
      if ( policy != null) {
         Grantee gtee = new Grantee( (Principal) user);
         java.io.FilePermission fileperm = 
                                new java.io.FilePermission("foo.txt", "read");
         policy.grant( gtee, fileperm);
      }
   } catch (Exception e) { /* print stack trace */ }
 
   out.println("</BODY>");
   out.println("</HTML>");
}

OracleAS JAAS Provider Policy Configuration

This section documents subject-based policy configuration that results from granting permissions when you use the OracleAS JAAS Provider Admintool or policy management APIs, as discussed in preceding sections. In OC4J, this configuration can be located in either the system-jazn-data.xml file or in Oracle Internet Directory, depending on the security provider.

The following topics are covered:

Note:

Configuration discussed here is for subject-based security only. Code-based security is configured in a Java 2 policy file (.policy), as discussed in "Specifying a Java 2 Security Manager and Policy File" and "Creating or Updating a Java 2 Policy File".

Policy Repository Setting in jazn.xml

The policy repository for security policies for an OC4J instance is the provider specified in the jazn.xml file, as indicated by the provider setting in the <jazn> element, as follows:

  • provider="XML" to use system-jazn-data.xml for policy configuration

  • provider="LDAP" to use Oracle Internet Directory for policy configuration

By default, provider in jazn.xml is set to "XML" to use system-jazn-data.xml as the policy repository. When you use Oracle Identity Management and associate an Oracle Internet Directory instance with the OC4J instance, the provider setting in jazn.xml is changed to "LDAP", resulting in the use of Oracle Internet Directory as the policy repository.

(Similarly, the provider setting in orion-application.xml specifies the security provider of the application, which is "XML" for the file-based provider, "LDAP" for Oracle Identity Management, and by convention is also "XML" for an external LDAP provider, custom login module, or Oracle Access Manager.)

Note:

Policy repository configuration in jazn.xml (such as settings for the provider and location attributes of the <jazn> element) is OC4J instance-level configuration. If you deploy an application to the OC4J instance, and the application configures a different provider, the result would be a mixed usage where the provider configured in orion-application.xml would be the identity store used for authentication, while the provider specified in jazn.xml would be the policy store used for authorization.

Policy Configuration in system-jazn-data.xml

For the file-based provider, Oracle Access Manager, an external LDAP provider, or a custom login module, policy configuration is located in the <jazn-policy> element of the system-jazn-data.xml file.

As an example, we repeat one of the grantperm examples from "Granting Permissions through the OracleAS JAAS Provider Admintool":

% java -jar jazn.jar -grantperm myrealm -role developers \
     com.evermind.server.rmi.RMIPermission login

This results in <jazn-policy> configuration such as in the following example:

<jazn-data>
   ...
   <jazn-policy>
     <grant>
       <grantee>
         <principals>
           <principal>
             <realm-name>myrealm</realm-name>
             <type>role</type>
             <class>oracle.security.jazn.XMLRealmRole</class>
             <name>developers</name>
           </principal>
         </principals>
       </grantee>
       <permissions>
         <permission>
           <class>com.evermind.server.rmi.RMIPermission</class>
           <name>login</name>
         </permission>
       </permissions>
     </grant>
     ...
   </jazn-policy>
   ...
</jazn-data>

Policy Configuration in Oracle Internet Directory

For Oracle Identity Management (the LDAP-based provider), policy configuration is located in Oracle Internet Directory. As with system-jazn-data.xml, policy information stored in Oracle Internet Directory is accessible through the OracleAS JAAS Provider Admintool or policy management APIs.

Specification of the Oracle Policy Provider

If you use the Java virtual machine shipped with Oracle Application Server, the JAAS policy provider supplied with OracleAS JAAS Provider is automatically specified as the policy provider to use in OC4J. If you use another JVM (in other words, if you run an application outside OC4J), then the Oracle JAAS policy provider, oracle.security.jazn.spi.PolicyProvider, must be explicitly specified as the policy provider. (By default, a non-Oracle JVM uses the Sun Microsystems JAAS provider.)

You can specify Oracle-specific JAAS properties, such as the policy provider, in a security properties file that you supply to the JVM when you run OC4J. Oracle offers a default security properties file, ORACLE_HOME/j2ee/home/config/jazn.security.props, that specifies oracle.security.jazn.spi.PolicyProvider as the policy provider to use in OC4J, with the following configuration:

auth.policy.provider=oracle.security.jazn.spi.PolicyProvider

To append default Oracle-specific security property settings, including the above specification of the Oracle JAAS policy provider, to existing security properties, set the java.security.properties system property as follows:

-Djava.security.properties=ORACLE_HOME/j2ee/home/config/jazn.security.props

To replace all security properties with the Oracle properties (note the two equals signs, "=="):

-Djava.security.properties==ORACLE_HOME/j2ee/home/config/jazn.security.props

Authorization Coding and Configuration

This section provides discussion and examples of the following steps to check authorization during runtime:

  1. Using J2EE Authorization APIs

  2. Obtaining a Subject

  3. Using the checkPermission() Method

  4. Configuring and Using JAAS Mode

  5. Enabling the Java Authorization Contract for Containers (optional extension of J2EE authorization)

Samples here use a servlet method, but the basic functionality is similar for EJBs.

See Also:

Using J2EE Authorization APIs

This sample servlet doGet() method uses standard J2EE authorization methods to retrieve a user and principal, and determine whether a user is in the specified role.

public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
    ServletOutputStream out = response.getOutputStream();

    response.setContentType("text/html");
    out.println("<HTML><BODY bgcolor=\"#FFFFFF\">");
    out.println("Time stamp: " + new Date().toString());
    out.println("request.isUserInRole('ar_developers') = " +
                 request.isUserInRole("ar_developers") + "<br>");
    out.println("</BODY>");
    out.println("</HTML>");
}

Obtaining a Subject

To perform authorization in your code, you will often have to obtain a Subject instance for the authenticated user who is attempting to access resources. You can accomplish this through standard JAAS functionality, using the static Subject.getSubject() method and specifying an access control context.

Typically, use the default access control context:

mysubject = Subject.getSubject(AccessController.getContext());

Alternatively, you can specify a particular access control context (such as one you have constructed from a set of protection domains, for example):

mysubject = Subject.getSubject(acc);

Note that when you use JAAS mode, OC4J associates an authenticated subject and its permissions with the default access control context and its permissions.

Using the checkPermission() Method

You will typically use a checkPermission(Permission) call in your authorization code, which checks whether the access request indicated by the specified permission should be allowed, based on the security policy currently in effect, and throws an exception if not.

This method is available in the AccessController and AccessControlContext classes. Assuming you use the default implementations (provided with the Sun JDK), the checkPermission() method of either class can enforce Java 2 (code-based) policy in your application regardless of whether a security manager is enabled.

When you use a security manager, the method is also available in the SecurityManager class, but the default SecurityManager implementation of checkPermission() calls AccessController.checkPermission().

You will typically use the AccessController.checkPermission() method, which is static. This call uses the default access control context (the context inherited when the thread was created). If you want the permissions check to be with respect to some other context, however, you can call the instance method checkPermission() on a particular AccessControlContext instance. The following example uses the AccessController method:

//create permission
      FilePermission perm = new FilePermission("/home/developer/foo.txt","read");
      //check permission
      AccessController.checkPermission(perm);

In OC4J, any JAAS mode setting is relevant with respect to what the access control context consists of when AccessController.checkPermission() is called, as follows:

  • With no JAAS mode (jaas-mode="null"), checkPermission() enforces code-based security based on the security policy in effect, as presumably specified in a Java 2 policy file. There is no provision for subject-based security.

  • With doAs JAAS mode (jaas-mode="doas"), checkPermission() enforces a combination of code-based and subject-based security according to the new access control context created through the doAs() block within which OC4J executes your application code. OC4J appends the permissions of the subject to the permissions of the default access control context.

  • With doAsPrivileged JAAS mode (jaas-mode="doasprivileged"), checkPermission() has the same functionality as in doAs mode, but OC4J uses a null access control context, as specified when OC4J calls doAsPrivileged(). This is to use subject-based security only.

Configuring and Using JAAS Mode

In this example, the doGet() method shown in "Using J2EE Authorization APIs" is expanded to create and check permissions. Furthermore, assume the JAAS mode doAsPrivileged, which is set with configuration such as the following in the application orion-application.xml file:

<orion-application ... >
   ...
   <jazn ... jaas-mode="doAsPrivileged" />
   ...
</orion-application>

The code follows, using two different ways to check permissions, for demonstration purposes. Because of the JAAS mode setting, the action method, in this case doGet(), will be executed by OC4J within a Subject.doAsPrivileged() block for the authenticated subject.

public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
       ServletOutputStream out = response.getOutputStream();
 
       response.setContentType("text/html");
       out.println("<HTML><BODY bgcolor=\"#FFFFFF\">");
       out.println("Time stamp: " + new Date().toString());
       out.println("request.isUserInRole('ar_developers') = " +
                    request.isUserInRole("ar_developers") + "<br>");
 
      //create Permission
      FilePermission perm = new FilePermission("/home/developer/foo.txt","read");
      {
         // CHECK PERMISSION VIA ACCESS CONTROLLER
         AccessController.checkPermission(perm);

         // CHECK PERMISSION VIA JAAS POLICY
         //get current AccessControlContext
         AccessControlContext acc = AccessController.getContext();
         
         javax.security.auth.Policy currPolicy =
                                    javax.security.auth.Policy.getPolicy();
 
         // Query policy now
         out.println("Policy permissions for this subject are " + 
                      currPolicy.getPermissions(Subject.getSubject(acc),null));
 
         //Check Permissions
         out.println("Policy.implies permission: "+ perm +" ? " +
         currPolicy.getPermissions(Subject.getSubject(acc),null).implies(perm));
      }
      out.println("</BODY>");
      out.println("</HTML>");
   }

Enabling the Java Authorization Contract for Containers

This section describes how to enable the Oracle JACC provider in OC4J. With JACC, J2EE security constraints are translated into Java 2 permissions to effectively provide an extended version of J2EE authorization, using the same configuration and code for authorization in your application.

The following topics are covered:

Note:

JACC is supported only for the file-based provider. Generated policies are stored in system-jazn-data.xml.

System Property to Enable JACC Features

By default, JACC is disabled in OC4J. It can be enabled with the following system property setting at OC4J startup:

-Doracle.oc4j.security.jacc=true

System Properties to Specify the JACC Provider

To employ a JACC provider, the system properties described in Table 5-2 must be set appropriately at application server startup. For the Oracle JACC provider, this happens automatically when you enable JACC, with the properties being set as shown in parentheses.

Table 5-2 System Properties for the JACC Provider

Property Description

javax.security.jacc.policy.provider

Class name of the policy provider (oracle.security.jacc.provider.J2SEPolicy)

javax.security.jacc.policy. PolicyConfigurationFactory.provider

Class name of the policy mapping configuration factory (oracle.security.jacc.provider. JACCPolicyConfigurationFactory)

oracle.security.jacc.provider. RoleMappingConfigurationFactory.provider

Class name of the role mapping configuration factory (oracle.security.jacc.provider. JACCRoleMappingConfigurationFactoryImpl)


Authorization Strategies

For each of the key Java security models discussed earlier—J2EE, Java 2, and JAAS—this section summarizes when it may be advantageous to use it, and how it works. Complete operational details are provided elsewhere in this manual (mostly earlier in this chapter).

Considering J2EE Security

J2EE (static role-based) security is a coarse-grained model that specifies what security roles can access a Web application or EJB.

When Should You Use It?

In a J2EE application, this is the simplest and most basic form of security. Almost any J2EE application will use it, and it will often be enough to suit your needs. It is standard and therefore platform-independent.

Because of its limitations, however, it is sometimes used in conjunction with the other security models. Note that with J2EE security alone, you cannot control access to particular resources or define particular permissions for a role. You also cannot control access by particular code entities. In addition, the J2EE security model is a static model; policies cannot be changed at runtime.

How Do You Set It Up?

Set up J2EE security through standard specifications for security roles, role-linking, and security constraints through the web.xml and ejb-jar.xml files, in addition to specifications for role-mapping through the OC4J-specific descriptors such as orion-application.xml.

If you use only J2EE security, JAAS mode is unnecessary (jaas-mode="null").

How Is It Enforced?

J2EE security is enforced by the J2EE container (OC4J).

Considering Java 2 Security

Java 2 (code-based) security controls access to resources based on the location of executing code or on code signers.

When Should You Use It?

Use Java 2 security when your application must check code-based permissions, perhaps regardless of the user or role trying to access it. With Java 2 security, an administrator can enable or disable a security manager to control when the security manager performs security checks.

Generally, code-based security and the use of a security manager is required only if a situation may arise where the application server is exposed to untrusted code. Also be aware that there may be a performance impact with the use of a security manager.

Java 2 security may be used in conjunction with either J2EE security, JAAS security, or both.

How Do You Set It Up?

Specify Java 2 policies through a standard .policy file, typically named java.policy or java2.policy. The policy file ORACLE_HOME/j2ee/home/config/java2.policy is supplied with OC4J and includes permissions that are required for OC4J to run with a security manager.

Oracle provides no tools to maintain Java 2 policy files; you must do so manually or use tools provided by the JDK vendor or a third-party vendor.

If you use Java 2 security alone or with J2EE security only, JAAS mode is unnecessary (jaas-mode="null").

How Is It Enforced?

For Java 2 security policies to be enforced by an application server and the underlying JDK, a security manager must be enabled.

For Java 2 security policies to be enforced within your application:

  • If you want the capability of code-based security in your application, but with an administrator being able to control when the security checks are performed, you can choose to enforce code-based security only when a security manager is enabled. In this case, you can use the checkPermission() method of the SecurityManager instance.

    Be aware that for this scenario, the JVM must be started with a security manager enabled.

  • If code-based security requirements in your application are independent of a security manager, you can choose to enforce code-based security within your application regardless of the presence of a security manager. In this case, you can use the static AccessController.checkPermission() method to check permissions.

    In this scenario, it is important to note that the overall environment will not be secure without a security manager. Other code in the environment, including JDK classes, will not be running in a secure mode.

  • To specify the particular protection domains to be checked, you can construct an AccessControlContext instance from an array of ProtectionDomain instances, and call the checkPermission() method on the AccessControlContext instance. (This is not a common usage scenario, however.)

Considering JAAS Security

JAAS (subject-based) security is a relatively fine-grained model that controls access to resources according to the particular permissions of the authenticated subject.

When Should You Use It?

Usually, the coarser-grained security of the J2EE model will suffice. JAAS security is more complicated to administer and deploy; however, JAAS security is valuable if you want finer control over resources, such as:

  • According to factors other than whether the resource is accessed as part of the execution of a Web module or EJB

  • According to individual permissions that can be granted or revoked either by an administrator beforehand or in your code at runtime

J2EE security, by contrast, is more static—access control cannot be modified at runtime.

JAAS security is typically used together with J2EE security, and may also be used together with Java 2 security.

How Do You Set It Up?

You can grant (or revoke) permissions either beforehand, using the OracleAS JAAS Provider Admintool (as shown in "Granting Permissions through the OracleAS JAAS Provider Admintool") or at runtime through OracleAS JAAS Provider APIs (as shown in "Using OracleAS JAAS Provider Policy Management APIs"). The resulting JAAS (subject-based) policy is reflected in system-jazn-data.xml, or Oracle Internet Directory if you use Oracle Identity Management as the security provider.

How you set the JAAS mode is also relevant. To use JAAS authorization without Java 2 (code-based) authorization, use the doAsPrivileged JAAS mode by setting jaas-mode="doasprivileged", and check permissions by using the Policy.implies() method.

To use JAAS authorization together with Java 2 authorization:

  • Use the doAs JAAS mode by setting jaas-mode="doas".

  • Specify Java 2 policies through a standard .policy file, typically the java2.policy file supplied by Oracle.

Note:

If a resource being accessed in doAsPrivileged mode is a resource defined by the JVM vendor, additional security checks may be performed if a security manager is enabled.

How Is It Enforced?

You can enforce JAAS security through the AccessController.checkPermission() method or Policy.implies() method.

If you are also using Java 2 security and have a security manager enabled, you can alternatively use the SecurityManager.checkPermission() method.

(Also refer to earlier discussion regarding enforcement of Java 2 policy.)