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

2 Java Platform Security

This chapter provides an overview of standard security models that can be used with Java and J2EE applications, covering the following topics:

Note:

The J2EE, Java 2, and JAAS security models are somewhat independent of each other and can be used separately or in combinations. Strategies are discussed in "Authorization Strategies".

See Also:

J2EE Security Model

J2EE defines a declarative authorization model for container-managed security that decouples applications from the underlying security infrastructure. Authorization policy (an association between resources and users or roles) is expressed statically in the application deployment descriptors, rather than in application code. Authorization is role-based and is granted at access-level, typically protecting resources such as a Web URL or an EJB method.

This section discusses the following J2EE security features:

Web Application Authentication and Authorization

This section discusses topics for Web application security, primarily involving declarative security configuration. There is also discussion of APIs for more advanced programmatic features, where security functionality can be determined at runtime.

The following topics are covered:

Web Application Standard Authentication Methods

Several standard methods of authentication can be used to access a J2EE Web application:

  • Basic

    With basic authentication, the user is prompted directly for a user name and password, without going through a single sign-on implementation.

  • Digest

    With the digest authentication mechanism, the password that a client presents to authenticate itself is encrypted through the use of an MD5 digest. This is transmitted in the request message. From a user perspective, digest authentication behaves in the same way as basic authentication. (In OC4J, the digest method is not supported for an external LDAP provider or custom provider.)

  • Form

    When the user attempts to access a protected resource through form-based authentication, OC4J displays an application-specific login screen, prompting for user name and password.

  • Client-cert

    This method, used in conjunction with the Secure Sockets Layer (SSL), authenticates the client through HTTPS. The user must possess a public key certificate.

Notes:

  • OC4J also supports several Oracle-specific single sign-on authentication methods, as summarized in "Overview of Oracle Application Server Single Sign-On Alternatives".

  • For either the file-based provider or Oracle Identity Management, if you are not using single sign-on, we recommend digest authentication as a more secure solution than basic authentication.

Web Application URL-Based Authorization

In the J2EE security model, Web resources to be secured are identified by their URL patterns. This is specified in the web.xml file of the Web application. For example, the following excerpt is from the configuration to protect resources under the URL pattern "/resource" of an application.

<web-resource-collection>
    <web-resource-name>resource access</web-resource-name>
    <url-pattern>/resource</url-pattern>
  </web-resource-collection>

This is part of a security constraint in web.xml that also specifies the J2EE logical role that is allowed to access the resource. J2EE logical roles, discussed in the J2EE specification, include developers (application component providers), assemblers, deployers, and system administrators.

For example, assume the J2EE role sr_developers is declared in the web.xml file. The security constraint to allow this role to access the resource would look like this:

<security-constraint>
    <web-resource-collection>
      <web-resource-name>resource access</web-resource-name>
      <url-pattern>/resource</url-pattern>
    </web-resource-collection>
    <!-- authorization -->
    <auth-constraint>
      <role-name>sr_developers</role-name>
    </auth-constraint>
 </security-constraint>

The sr_developers role can then be mapped to the appropriate deployment role (a role defined in the security provider) in a later OC4J-specific configuration step.

Run-As Mode and Propagated Identities in Web Applications

For calls from a Web application to an EJB, the default mode is for the Web client's security identity to be propagated to the EJB container.

There are also situations where a Web container must allow Web clients that are unknown to the Web container or EJB container to make calls. This includes the scenario of supporting Web clients that have not authenticated themselves to the container, such as to allow access of resources from the Internet.

For situations such as these, the web.xml file of a Web application may specify a "run-as" identity through the <run-as> subelement of the <servlet> element:

<run-as>
   <role-name>sr_developers</role-name>
</run-as>

The Web container propagates the security identity for any call from a servlet to the EJB layer, in terms of the role specified in the <run-as> element, which must be a role previously declared through a <security-role> element. The run-as identity hides the propagated identity.

Related Web Application APIs

For more advanced uses, there are standard J2EE programmatic features that allow Web applications to retrieve information about a user. You can use these methods in determining if a user should be allowed to access a resource.

A Web application can use the following methods in a javax.servlet.http.HttpServletRequest instance:

  • Principal getUserPrincipal()

    Returns a principal object containing the name of the authenticated user making the request (or null if the user has not been authenticated).

    Where identity propagation is used between a servlet and an EJB, the principal name returned by the getUserPrincipal() method of the calling servlet would be the same as that returned by the getCallerPrincipal() method of the EJB.

  • String getRemoteUser()

    Returns the login name of the authenticated user making the request (or null if the user is not authenticated).

  • boolean isUserInRole(String rolename)

    Determines whether the authenticated user making the request is a member of the specified role.

Notes:

  • APIs documented here can be used with either the file-based provider or Oracle Internet Directory as the user repository.

  • The com.evermind.security.User and Group classes from previous releases are deprecated. (They will not be supported in the 11g release.) Use standard JAAS APIs and signatures instead, such as for getUserPrincipal(), utilizing populated subjects as appropriate.

See Also:

  • "Principals and Subjects" for a general discussion of principals

  • Oracle Containers for J2EE Security Java API Reference (Javadoc)

Enterprise JavaBeans Authentication and Authorization

This section discusses topics for EJB security, primarily involving declarative security configuration. There is also discussion of APIs for more advanced programmatic features, where security functionality can be determined at runtime.

The following topics are covered:

EJB Authentication

An EJB being accessed in a remote container requires authentication of the client that is accessing it:

  • A standalone Java client can pass credentials through user and password settings in the jndi.properties file.

  • An EJB or Web client can pass credentials through a javax.naming.InitialContext instance, which is created to look up the remote EJB.

In addition, where ORMIS is used (ORMI in conjunction with the Secure Sockets Layer), you can use client-cert authentication with EJBs.

EJB Method-Based Authorization

In the J2EE security model, EJB resources to be secured are identified by their method names or name masks within the particular EJB. This is specified in the ejb-jar.xml file of the EJB. For example, the following excerpt is from the configuration to protect all methods of a PurchaseOrder bean:

<method>
   <ejb-name>PurchaseOrder</ejb-name>
   <method-name>*</method-name>
  </method>

This is part of a method permission in ejb-jar.xml that also specifies the J2EE logical role that is allowed to access the resource. J2EE logical roles, discussed in the J2EE specification, include developers (application component providers), assemblers, deployers, and system administrators.

The following excerpt allows the role myMgr to access any method in the PurchaseOrder EJB:

<method-permission>
  <role-name>myMgr</role-name>
  <method>
   <ejb-name>PurchaseOrder</ejb-name>
   <method-name>*</method-name>
  </method>
 </method-permission>

The myMgr role can then be mapped to the appropriate deployment role (a role defined in the security provider) in a later OC4J-specific configuration step.

Run-As Mode and Propagated Identities in EJB Applications

The ejb-jar.xml deployment descriptor can include specification of a "run-as" identify for an EJB, which can be used in conjunction with identity propagation when one EJB calls a second EJB. The run-as identity hides the propagated identity, and applies to the called EJB as a whole and is used as the identity in executing its methods. The identity would be a J2EE logical role previously declared through a <security-role> element.

Use the <run-as> subelement of the <security-identity> element for this purpose:

<run-as>
   <role-name>admin</role-name>
</run-as>

Related EJB APIs

For more advanced uses, there are standard J2EE programmatic features that allow EJBs to retrieve information about a caller. You can use these methods in determining if a caller should be allowed to access a resource.

An EJB application can use the following methods in a javax.ejb.EJBContext instance:

  • Principal getCallerPrincipal()

    Returns a principal object that identifies the caller.

    Where identity propagation is used between a servlet and an EJB, the principal name returned by the getUserPrincipal() method of the calling servlet would be the same as that returned by the getCallerPrincipal() method of the EJB.

    Where identity propagation is used between EJBs, the client identity is propagated to all EJBs downstream in the call chain, and the principal name returned by getCallerPrincipal() would be the same for all EJBs in the call chain. This assumes, however, that subject.propagation permission (discussed in "Grant RMI Permission for Subject Propagation") is granted to all authenticating users in the sequence.

  • boolean isCallerInRole(String rolename)

    Determines whether the caller is a member of the specified role.

Notes:

  • APIs documented here can be used with either the file-based provider or Oracle Internet Directory as the user repository.

  • The com.evermind.security.User class from previous releases is deprecated. (It will not be supported in the 11g release.) Use standard JAAS APIs instead, utilizing populated subjects as appropriate.

See Also:

Identity Propagation

Identity propagation in J2EE refers to the forwarding of a security identity from a Web module or EJB to an EJB that the original Web module or EJB invokes:

  1. An initiating application client or Web client uses a security identity to access an intermediate EJB or Web module.

  2. The intermediate EJB or Web module invokes a target EJB by forwarding, or propagating, a security identity to access the target EJB.

There are typically two models for propagation:

  • If the target container trusts the intermediate container, the caller identity of the intermediate EJB or Web module can be propagated to the target EJB.

  • If the target container expects access by a particular identity, that identity can be propagated to the target EJB.

In general, the target container must trust the intermediate container, because no data is made available for the target container to use in authenticating the propagated identity. Because the propagated identity will presumably be used for authorization checks, such as isCallerInRole(), it is critical for the propagated identity to be authentic.

In OC4J, identity propagation is referred to as subject propagation.

Java 2 Security Model

The Java 2 Security Model is supported as part of Oracle Application Server security. Note, however, that it is not implemented in OC4J itself, but rather in the underlying JDK.

This security model provides developers and administrators with increased control over many aspects of enterprise component, servlet, and application security. The Java 2 Security Model is capability-based and enables you to establish protection domains and to set security policies (discussed in "Java 2 Authorization: Java 2 Security Policies") for these domains.

The Java 2 Security Model by itself, however, has certain limitations. It is based on application code, as opposed to being declarative in deployment descriptors. It also has no policy management API, and uses a file-based implementation that does not scale well.

The following sections discuss characteristics and features of the Java 2 Security Model:

See Also:

Code-Based Security

Code-based security restricts the operations that applications can perform, by applying sets of permissions to executing code. This protects against the actions of untrusted or possibly malicious code, and could be to accomplish any of the following, for example:

  • Restrict database access to only trusted applications

  • Disallow the execution of code downloaded from the Internet

  • Limit operations that can be performed by third-party code

Code-based security differs from role-based security in that it is not based on users or user roles. Permissions are granted based on code characteristics, such as where the code is coming from and whether it is digitally signed (and by whom).

A codebase is a URL indicating code location, such as the following examples:

  • file: (any file on the local file system)

  • http://*.oracle.com (any file on any host at oracle.com)

  • file:${j2ee.home}/lib/oc4j-internal.jar

A codesource expands this concept to optionally include an array of certificates (stored in a Java keystore) to verify signed code originating from the location. A codesource is represented by a java.security.CodeSource instance, which is constructed by specifying a java.net.URL instance and an array of java.security.cert.Certificate instances.

The standard CodeSource class includes the following methods:

  • Certificate[] getCertificates()

    Returns an array of the certificates associated with this codesource.

  • URL getLocation()

    Returns the URL location associated with this codesource.

  • boolean equals(Object)

    Compares the specified object (presumably a codesource object) with this codesource object for equality. Two codesources are considered equal if their locations are identical and they have the same set of certificates (though it is not necessary for the certificates to be in the same order).

  • boolean implies(CodeSource)

    Performs a series of comparisons to see if this codesource "implies" the specified codesource. For example, codesources with the following locations, and null certificates, all imply the codesource with location http://java.sun.com/classes/foo.jar and null certificates:

    http:
    http://*.sun.com/classes/*
    http://java.sun.com/classes/-
    http://java.sun.com/classes/foo.jar
    

See Also:

Security Permissions

Permissions are the basis of the Java 2 Security Model. All Java classes (whether run locally or downloaded remotely) are subject to a configured security policy that defines the set of permissions available for those classes. Each permission represents a specific access to a particular resource.

The java.security.Permission class is an abstract class that represents access to a given resource, and optionally a specified action on that resource. A key method of this class is implies(Permission permission), which checks whether the actions of the specified permission are implied by the actions of the permission instance upon which the method is called.

Here are common types of permissions and the classes that represent them (all extending Permission, either directly or indirectly):

  • java.security.AllPermission

  • java.lang.RuntimePermission (includes only a resource target)

  • java.io.FilePermission (includes a resource and actions)

Table 2-1 identifies characteristics of a Java permission instance.

Important:

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

Table 2-1 Java Permission Instance Characteristics

Element Description Example

Class name

Permission class

java.io.FilePermission

Target

Target name (resource) to which this permission applies

Directory /home/*

Actions

Actions associated with this target

Read, write, and execute permissions on directory/home/*


Protection Domains

A protection domain associates permissions with codesources (defined in "Code-Based Security"). The policy currently in effect is what determines protection domains. In the default implementation of the Policy class, a protection domain is one grant entry in the file.

Each Java class is associated with a protection domain when it is loaded. Specifically, each class being loaded is associated with a java.security.ProtectionDomain instance. The permissions granted to this protection domain may be statically bound or dynamically determined when an access control check is performed. Each protection domain is assigned a set of permissions based on a configured security policy when the JVM is started.

A ProtectionDomain instance contains one or more codesources. It may also contain a Principal array describing who is executing the code, a classloader reference, and a permission set (java.security.PermissionCollection instance) representing a collection of Permission objects.

Figure 2-1 shows an example of the relationship between code, protection domains, and permission sets. In this example:

  • Protection Domain 1 associates the codesources e.jar, c.class, r.class, and i.jar with Permission Set 1.

  • Protection Domain 2 associates the codesources s.class, u.jar, t.class, and y.class with Permission Set 2.

  • The System Domain associates all JAR files in the classpath with Special Permissions.

Figure 2-1 Protection Domains

Description of Figure 2-1 follows
Description of "Figure 2-1 Protection Domains"

See Also:

Java 2 Authorization: Java 2 Security Policies

In Java 2, a policy is a mapping between running code and resource access permissions granted to the code. Elements of a policy include codesources, permissions, and protection domains, all described in preceding sections.

In the J2SE implementation, a policy is represented by a java.security.Policy instance. Note that this class, and the Java 2 Security Model in general, is implemented in the underlying JDK, not in OC4J itself.

Java 2 policies, for code-based permissions, are declared in .policy files, such as java.policy or java2.policy (typical examples). A policy contains a collection of permission grants to codebases, and may contain a reference to a keystore (described in "Key Encryption and Exchange"). The following are typical locations for Java 2 policy files:

  • JAVA_HOME/lib/security/java.policy

  • USER_HOME/java.policy

  • ORACLE_HOME/j2ee/home/config/java2.policy

    (When you start OC4J with a security manager, the file in this location contains the relevant permissions.)

Java 2 Authorization: Security Managers and Access Controllers

A security manager (java.lang.SecurityManager instance) allows an application to implement Java 2 security policies. For any given operation that is attempted, the security manager allows the application to determine what the operation is and whether it should be allowed. The SecurityManager class has a number of checkXxx() methods, each of which checks whether the operation Xxx is allowed, and throws an exception if it is not. This includes the instance method checkPermission(Permission), which throws an exception if a requested access, specified by the given permission, is not permitted by the security policy currently in effect.

An access controller (java.security.AccessController instance) is also involved in access-control operations and decisions. The default implementation of the SecurityManager method checkPermission(Permission) actually calls the AccessController static method checkPermission(Permission). Note, however, that the AccessController.checkPermission(Permission) method does not require a security manager.

Basically, an access controller is used to do the following:

  • Decide whether access to a system resource should be allowed or denied, based on the security policy currently in effect.

  • Mark code as being privileged, thus affecting subsequent access determinations.

  • Obtain a snapshot of the current calling context so access-control decisions from a different context can be made with respect to the saved context.

Any application that controls access to system resources should invoke AccessController methods if it is to use the specific security model and access control algorithm utilized by these methods. If, on the other hand, the application wishes to defer the security model to that of the SecurityManager installed at runtime, then it should instead invoke corresponding methods in the SecurityManager instance.

In comparison, SecurityManager represents the concept of a central point of access control, while AccessController implements a particular access control algorithm, with special features such as the doPrivileged() method, which performs a specified privileged action (an action requiring specific privileges) with privileges enabled.

There is also the concept of an access control context (a java.security.AccessControlContext instance), which you can use to restrict access to resources based on a particular security context. For example, you can construct an access control context from a particular array of protection domain instances. The AccessControlContext class also defines a checkPermission(Permission) method, which in this case makes access decisions based on the AccessControlContext instance from which it is called, rather than on the context of the current execution thread. So the usefulness of an AccessControlContext instance is for a situation where a security check that should be performed with respect to a particular context must be performed from a different context.

Important:

In order to use Java 2 policies, you must specifically enable a security manager, as discussed in "Specifying a Java 2 Security Manager and Policy File". This allows the JDK and the Subject methods doAs() and doAsPrivileged() (discussed later in this chapter) to check permissions of executing code.

See Also:

Java Authentication and Authorization Service

The Java Authentication and Authorization Service (JAAS) is a Java package that enables applications to authenticate and enforce access controls upon users. It is designed to complement Java 2 security, basing authorization on who is running code (subject-based security) in addition to what code is running (the code-based security of Java 2).

JAAS also implements a Java version of the standard Pluggable Authentication Module (PAM) framework. This enables an application to remain independent from the authentication service, and supports the use of custom authentication modules.

JAAS extends the access control architecture of the Java 2 Security Model to support subject-based authorization. It also supports declarative security settings, in deployment descriptors, instead of being limited to code-based security settings.

OC4J includes a scalable JAAS provider and uses JAAS as a standard mechanism for fine-grained authorization, as opposed to using a proprietary mechanism. OC4J supports JAAS authorization for both Web-based and EJB-based applications.

The following sections discuss JAAS characteristics and features:

See Also:

Principals and Subjects

A principal is a specific identity, such as a user named frank or a role named hr. A principal is represented by an instance of a class that implements the java.security.Principal interface. A principal class must define a namespace that contains a unique name for each instance of the class.

A subject represents a grouping of related information for a single user of a computing service, such as a person, computer, or process. This related information includes the subject's identity and roles, and other security-related attributes such as passwords, cryptographic keys, or other credentials. A subject is represented by an instance of the javax.security.auth.Subject class.

After authentication of a user, a Subject instance represents the authenticated user, and then appropriate Principal instances are added to the Subject instance. The Principal instances are used in authorizing the authenticated user to perform specific privileged actions.

JAAS Authentication: Login Modules

Within the JAAS pluggable authentication framework, an application server and any underlying authentication services remain independent from each other. Authentication services can be plugged in through JAAS login modules without requiring modifications to the application server or application code. A login module is primarily responsible for authenticating a user based on supplied credentials (such as a password), and adding the proper principals (such as roles) to a subject. Possible types of JAAS login modules include a principal-mapping module, a credential-mapping module, or a Kerberos module.

About Login Modules

A login module is an instance of a class that implements the javax.security.auth.spi.LoginModule interface, and is plugged in under an application to provide a particular type of authentication.

Within this framework, the javax.security.auth.login.LoginContext class provides the basic methods used to authenticate subjects such as users, roles, or computing services (when a user tries to log in to the application, for example). An application instantiates this class with a name and a callback handler (described shortly). When the login() method of a LoginContext instance is invoked by an application that a subject is trying to access, the LoginContext instance consults configuration settings, using a mechanism that employs the name that was passed in, to determine the appropriate login module to invoke for the application. Figure 2-2 summarizes this, and shows functions of the login module.

A callback handler is a javax.security.auth.callback.CallbackHandler instance that allows a login module to interact with a user to obtain login information. The only method specified by CallbackHandler is the handle(Callback[]) method, which takes an array of callbacks, which are instances of a class that implements the java.security.auth.callback.Callback interface. Callbacks do not retrieve or display requested information from the underlying security service, but simply provide the functionality to pass the requests to an application and, as applicable, to return the requested information back to the security service. Callback implementations in the javax.security.auth.callback package include: a name callback handler (NameCallback) to handle a user name, a password callback handler (PasswordCallback) to handle a password, and a text input callback handler (TextInputCallback) to handle any field in a login form other than a user name or password field.

Different login modules can be configured with different applications, and a single application can use multiple login modules. The JAAS framework defines a two-phase authentication process to coordinate the login modules configured for an application.

Custom or external (third-party) login modules may be used with any given application. Oracle provides the login modules RealmLoginModule (for the file-based and LDAP-based providers), LDAPLoginModule (for external LDAP providers), CoreIDLoginModule (for the Oracle Access Manager), and DBTableOraDataSourceLoginModule (to use a database identity store).

Note:

An application that uses declarative J2EE authentication with OC4J and the OracleAS JAAS Provider does not have to create a LoginContext instance; it is created by OC4J implicitly.

Stacking Login Modules

The JAAS PAM architecture allows an enterprise application to customize its authentication mechanism by defining a stack of login modules, each of which is independent and communicates to its own user repository.

The javax.security.auth.login.Configuration class is an abstract class to represent the configuration of login modules under an application. A Configuration instance specifies which login modules should be used for a particular application, and in what order the login modules should be invoked. The Configuration class is extended to provide an appropriate implementation.

For each login module, a control flag setting in the login module configuration determines whether that login module is "required", "requisite", "sufficient", or "optional", with the meanings of these settings being according to standard functionality of the Configuration class, as discussed in Table 9-5, "Login Module Control Flags".

A login configuration contains an ordered list of login modules specified by fully qualified class names, along with control flag settings and any option settings particular to each login module. Authentication proceeds down the module list in order. (In OC4J, the order is determined by the order in which the login modules are configured in the system-jazn-data.xml file.)

Overall authentication is governed by the individual login modules and their control flag settings.

JAAS Authorization: JAAS Security Policies

In JAAS, a policy is an association between resources and users or roles. With the integration of JAAS into Java 2 security, the Policy API handles queries based on principals, and the default policy implementation supports grant entries based on principals. In extending the Java 2 security model, access control is based not only on the code that is executing, but also on who is executing it. More specifically, a policy is a repository of authorization rules, containing information that answers the question: Given a grantee, what are the granted permissions of the grantee?

In OC4J 10.1.3.x implementations, a policy is represented by a javax.security.auth.Policy instance. This class is deprecated as of JDK 1.4, but still fully supported in OC4J 10.1.3.x implementations and the Sun Microsystems JDK and J2SE.

In OC4J, JAAS 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. (This functionality is comparable to that of a .policy file in the Java 2 Security Model.) These declarations grant permissions to users and roles, and are updated automatically when you use the OracleAS JAAS Provider Admintool to grant or revoke permissions.

JAAS Authorization: Subject Methods doAs() and doAsPrivileged()

The Subject class includes the following standard methods for authorization in the JAAS model:

  • Object doAs(Subject, PrivilegedAction)

    Performs the specified privileged action (a computation to be performed with privileges enabled) as the specified subject. This method associates the subject with the access control context (AccessControlContext instance) of the current thread (of the executing codesource), appending the subject's permissions to the permissions of that access control context and creating a new access control context with the combined permissions. Then the AccessController.doPrivileged() method is called with the specified action and the new access control context.

    The returned object is what is returned by the run() method of the privileged action. There is also a variation that takes java.security.PrivilegedExceptionAction instead of java.security.PrivilegedAction, for computations that can throw checked exceptions.

  • Object doAsPrivileged(Subject, PrivilegedAction, AccessControlContext)

    This method has the same functionality as the doAs() method, but within the specified access control context instead of using the access control context of the thread, appending the subject's permissions to the permissions of the specified context. Typical usage is actually to specify a null access control context, if you prefer that the codesource not be required to have access privileges.

Figure 2-3 shows a sample code stack for the doAs() and doAsPrivileged() methods, in this case for modifying a password file. In the doAsPrivileged() case, if we assume that a null access control context is passed, then the subject must have sufficient privileges to access the password file.

Figure 2-3 Code Stack for doAs() and doAsPrivileged() Methods

Description of Figure 2-3 follows
Description of "Figure 2-3 Code Stack for doAs() and doAsPrivileged() Methods"

Necessary Permissions for Principals for Subject doAs() Method

When you use the subject doAs() method with a privileged action, you must grant the necessary permissions for principals associated with the subject. You can use the OracleAS JAAS Provider Admintool to accomplish this; the resulting configuration appears under the <jazn-policy> element in the system-jazn-data.xml file.

The following example grants runtime permission "setContextClassLoader" to a PrincipalImpl principal named myapp:

% java -jar jazn.jar -grantperm sun.security.acl.PrincipalImpl \
      myapp java.lang.RuntimePermission setContextClassLoader

This results in the following configuration in system-jazn-data.xml:

<grant>
       <grantee>
         <principals>
          <principal>
            <class>sun.security.acl.PrincipalImpl</class>
            <name>myapp</name>
          </principal>
         </principals>
       </grantee>
       <permissions>
         <permission>
           <class>java.lang.RuntimePermission</class>
           <name>setContextClassLoader</name>
         </permission>
       </permissions>
      </grant>

Security Considerations during Development

This section discusses what you should consider during the development cycle for security. This includes a summary comparison between security models, and specific steps you should take in developing your application to ensure security.

Summary: Comparing Security Models for J2EE, Java 2, and JAAS

To summarize highlights of the J2EE, Java 2, and JAAS security models described in this chapter:

  • In the J2EE authorization model, resources to be secured are identified by their URL patterns (for Web applications) or method names or name masks (for EJBs). Authorization is enforced by the container based on declarative role-based security defined in deployment configuration, with no implementation in your code. Once access is granted, any functionality of the resource is available. This model is relatively coarse-grained, but suffices for many purposes. It is also static, in that the developer or deployer must know about the user population beforehand.

    In the J2EE model, authentication is managed by the container.

  • The Java 2 authorization model is code-based, restricting operations that applications can perform by applying sets of permissions (established in a Java 2 policy file that you define) that determine what code from any given codesource is allowed to do. (A codesource consists of a URL location of the code in question, and optionally an array of certificates.) Authorization checks are implemented in code, and performed by a security manager or access controller object. There is no static configuration for this model, other than the predefined policy files. This is an authorization model that is more dynamic and relatively fine-grained, where authorization is according to an adaptable security policy.

    As in the J2EE model, authentication is managed by the container.

  • The JAAS authorization model extends Java 2 security, with policy objects able to handle queries based on principals, and the default policy implementation supporting grant entries based on principals. As with Java 2 security, authorization is enforced within application code. With the JAAS extensions, access control is based not only on the code that is executing, but also on who is executing it. A policy object is able to retrieve permissions granted to principals associated with a specified codesource. As with the Java 2 model, there is no static configuration involved, aside from policy files. The JAAS model is more customizable and extensible than the J2EE model, with features such as custom permission types, and is also more fine-grained than the Java 2 model, given the ability to authorize according to principals. For example, while J2EE security is sufficient for general protection of a Web URL or EJB method, JAAS security would be required to control who may access a file in the file system, or who may access security policy, create a user, or change a password.

    JAAS is also the only one of these models that supports customized authentication, through custom login modules. In addition, you can authenticate against multiple user repositories.

As appropriate and necessary, you can use any model or a combination of the models within an application. All three models are fully supported in OC4J. It is advisable to limit yourself to the J2EE authorization model whenever it meets your needs, given that it is the least complicated to deploy and administer. You can extend your application to use Java 2 or JAAS security depending on your needs for finer-grained code-based or subject-based security.

See Also:

Steps to Develop a Secure J2EE Application

J2EE software development is based on a develop-deploy-manage cycle. The Oracle Application Server security implementation plays an important part in the deploy-manage part of the cycle. Developers can use the more convenient declarative security model instead of having to integrate security programmatically.

The following list summarizes the J2EE development cycle, with an emphasis on the tasks specific to developing secure applications.

  1. The developer creates Web components, enterprise beans, servlets, and application clients as desired.

    The Oracle Application Server security implementation offers programmatic interfaces, but the developer can create components without having to use those interfaces.

  2. The developer defines J2EE logical roles and assigns them privileges through security constraints, all through configuration in standard J2EE deployment descriptors.

  3. The assembler takes these components and combines them into an Enterprise Archive (EAR) file.

    As part of this process, the application assembler specifies options appropriate to the environment.

  4. The assembler defines application-level security constraints and resolves potential conflicts between module-level configurations.

  5. The deployer installs the EAR into an instance of OC4J.

    As part of the deployment process, the deployer may map J2EE roles to deployment users and roles, as discussed in "Specifying Security Role Mapping through Application Server Control".

  6. The system administrator maintains and manages the deployed application.

    This task includes creating and managing roles and users in the deployment environment as required by the application customers.

For finer-grained code-based or subject-based access control using Java 2 or JAAS features, there are also the following considerations:

  1. The developer identifies any resources that may be accessed and must be protected as appropriate.

  2. The developer defines permissions to protect these resources. (J2SE has predefined permissions that you can use where appropriate and sufficient.)

  3. The developer implements code for runtime authorization checks.

  4. The deployer, in consultation with the developer, defines the appropriate JAAS mode configuration for the application.

  5. The system administrator maintains any necessary policy configuration to enforce the desired permissions. Policy provisioning (such as permission grants through the OracleAS JAAS Provider Admintool) should be completed prior to runtime.

See Also:

  • Oracle Application Server Best Practices (available post-release) for information about best practices for security