Skip Headers
Oracle® Containers for J2EE Enterprise JavaBeans Developer's Guide
10g Release 3 (10.1.3)
B14428-02
  Go To Documentation Library
Home
Go To Product List
Solution Area
Go To Table Of Contents
Contents
Go To Index
Index

Previous
Previous
 
Next
Next
 

22 Configuring Security Services

This chapter explains security service configuration as it applies specifically to J2EE applications, including:

For more information, see:

Granting Permissions in Browser

If you download the EJB application as a client where the security manager is active, you must grant the following permissions before you can execute:

permission java.net.SocketPermission "*:*", "connect,resolve";
permission java.lang.RuntimePermission "createClassLoader";
permission java.lang.RuntimePermission "getClassLoader";
permission java.util.PropertyPermission "*", "read";
permission java.util.PropertyPermission "LoadBalanceOnLookup", "read,write";

Defining Users, Groups, and Roles in an EJB Application

For EJB authentication and authorization, you define the principals under which each method executes by configuring of the EJB deployment descriptor. The container enforces that the user who is trying to execute the method is the same as defined within the deployment descriptor.

The EJB deployment descriptor enables you to define security roles under which each method is allowed to execute. These methods are mapped to users or groups in the OC4J-specific deployment descriptor. The users and groups are defined within your designated security user managers, which uses either the Oracle Application Server Java Authentication and Authorization Service (JAAS) Provider (OracleAS JAAS Provider) or XML user manager. For a full description of security user managers, see the Oracle Containers for J2EE Services Guide.

For authentication and authorization, this section focuses on XML configuration within the EJB deployment descriptors. EJB authorization is specified within the EJB and OC4J-specific deployment descriptors. You can manage the authorization piece of your security within the deployment descriptors, as follows:

Users and groups are identities known by the container. Roles are the logical identities each application uses to indicate access rights to its different objects. The username/passwords can be digital certificates and, in the case of SSL, private key pairs.

Thus, the definition and mapping of roles is demonstrated in Figure 22-1.

Defining users, groups, and roles are discussed in the following sections:

Specifying Users and Groups

OC4J supports the definition of users and groups—either shared by all deployed applications or specific to given applications. You define shared or application-specific users and groups within either the OracleAS JAAS Provider or XML user managers. See the Oracle Containers for J2EE Services Guide.for directions.

Specifying Logical Roles in the EJB Deployment Descriptor

As shown in Figure 22-2, you can use a logical name for a role within your bean implementation, and map this logical name to the correct database role or user. The mapping of the logical name to a database role is specified in the OC4J-specific deployment descriptor. See "Mapping Logical Roles to Users and Groups" for more information.

Figure 22-2 Security Mapping

Description of Figure 22-2 follows
Description of "Figure 22-2 Security Mapping"

If you use a logical name for a database role within your bean implementation for methods such as isCallerInRole, you can map the logical name to an actual database role by doing the following:

  1. Declare the logical name within the <enterprise-beans> section <security-role-ref> element. For example, to define a role used within the purchase order example, you may have checked, within the bean's implementation, to see if the caller had authorization to sign a purchase order. Thus, the caller would have to be signed in under a correct role. In order for the bean to not need to be aware of database roles, you can check isCallerInRole on a logical name, such as POMgr, since only purchase order managers can sign off on the order. Thus, you would define the logical security role, POMgr within the <security-role-ref><role-name> element within the <enterprise-beans> section, as follows:

    <enterprise-beans>
    ...
      <security-role-ref>
       <role-name>POMgr</role-name>
       <role-link>myMgr</role-link>
      </security-role-ref>
    </enterprise-beans>
    
    

    The <role-link> element within the <security-role-ref> element can be the actual database role, which is defined further within the <assembly-descriptor> section. Alternatively, it can be another logical name, which is still defined more in the <assembly-descriptor> section and is mapped to an actual database role within the Oracle-specific deployment descriptor.


    Note:

    The <security-role-ref> element is not required. You only specify it when using security context methods within your bean.

  2. Define the role and the methods that it applies to. In the purchase order example, any method executed within the PurchaseOrder bean must have authorized itself as myMgr. Note that PurchaseOrder is the name declared in the <entity | session><ejb-name> element.

    Thus, the following defines the role as myMgr, the EJB as PurchaseOrder, and all methods by denoting the '*' symbol.


    Note:

    The myMgr role in the <security-role> element is the same as the <role-link> element within the <enterprise-beans> section. This ties the logical name of POMgr to the myMgr definition.

    <assembly-descriptor>
     <security-role>
      <description>Role needed purchase order authorization</description>
      <role-name>myMgr</role-name>
     </security-role>
     <method-permission>
      <role-name>myMgr</role-name>
      <method>
       <ejb-name>PurchaseOrder</ejb-name>
       <method-name>*</method-name>
      </method>
     </method-permission>
    ...
    </assembly-descriptor>
    
    

After performing both steps, you can refer to POMgr within the bean's implementation and the container translates POMgr to myMgr.


Note:

If you define different roles within the <method-permission> element for methods in the same EJB, the resulting permission is a union of all the method permissions defined for the methods of this bean.

Specifying a Role for an EJB Method

You can specify which security roles are allowed to invoke an enterprise bean method.

In an EJB 3.0 application, you can use annotations (see "Using Annotations").

In an EJB 3.0 or EJB 2.1 application, you can use the ejb-jar.xml deployment descriptor (see "Using Deployment XML").

Using Annotations

In an EJB 3.0 application, you can use the @RolesAllowed annotation to specify the security roles permitted to access methods in an application as Example 22-1 shows.

Example 22-1 @RolesAllowed

@RolesAllowed("Users")
public class Calculator
{
    @RolesAllowed("Administrator")
    public void setNewRate(int rate)
    {
    ...
    }
}

You can apply this annotation to a class, method, or both.

When applied to a method, the specification overrides class specification, if present.

For more information on security annotations, see "Using EJB 3.0 Security Annotations".

Using Deployment XML

The <method-permission><method> element is used to specify the security role for one or more methods within an interface or implementation. According to the EJB specification, this definition can be of one of the following forms:

  • Defining all methods within a bean by specifying the bean name and using the '*' character to denote all methods within the bean, as follows:

    <method-permission>
      <role-name>myMgr</role-name>
      <method>
        <ejb-name>EJBNAME</ejb-name>
        <method-name>*</method-name>
      </method>
    </method-permission>
    
    
  • Defining a specific method that is uniquely identified within the bean. Use the appropriate interface name and method name, as follows:

    <method-permission>
      <role-name>myMgr</role-name>
      <method>
        <ejb-name>myBean</ejb-name>
        <method-name>myMethodInMyBean</method-name>
      </method>
    </method-permission>
    

    Note:

    If there are multiple methods with the same overloaded name, the element of this style refers to all the methods with the overloaded name.

  • Defining a method with a specific signature among many overloaded versions, as follows:

    <method-permission>
      <role-name>myMgr</role-name>
      <method>
        <ejb-name>myBean</ejb-name>
        <method-name>myMethod</method-name>
        <method-params>
          <method-param>javax.lang.String</method-param>
          <method-param>javax.lang.String</method-param>
        </method-params>
      </method>
    </method-permission>
    
    

    The parameters are the fully-qualified Java types of the method's input parameters. If the method has no input arguments, the <method-params> element contains no elements. Arrays are specified by the array element's type, followed by one or more pair of square brackets, such as int[ ] [ ].

Specifying Unchecked Security for EJB Methods

If you want certain methods to not be checked for security roles, you define these methods as unchecked.

In an EJB 3.0 application, you can use annotations (see "Using Annotations").

In an EJB 3.0 or EJB 2.1 application, you can use the ejb-jar.xml deployment descriptor (see "Using Deployment XML").

Using Annotations

In an EJB 3.0 application, you can use the @PermitAll annotation to specify that all security roles are permitted to access methods in an application as Example 22-2 shows.

Example 22-2 @PermitAll

@RolesAllowed("Users")
public class Calculator 
{
    @RolesAllowed("Administrator")
    public void setNewRate(int rate) 
    {
    ...
    }
    @PermitAll
    public long convertCurrency(long amount) 
    {
    ...
    }
}

You can apply this annotation to a class or method.

When applied to a class, the specification applies to all methods.

When applied to a method, the specification applies only to that method.

When using this annotation, observe the restrictions described in "Using EJB 3.0 Security Annotations".

Using Deployment XML

The <method-permission><unchecked> element is used to specify that all security roles are permitted to access a method, as follows:

<method-permission>
  <unchecked/>
  <method>
     <ejb-name>EJBNAME</ejb-name>
     <method-name>*</method-name>
  </method>
</method-permission>

Instead of a <role-name> element defined, you define an <unchecked/> element. When executing any methods in the EJBNAME bean, the container does not check for security. Unchecked methods always override any other role definitions.

Specifying the runAs Security Identity

You can specify that all methods of an EJB execute under a specific identity. That is, the container does not check different roles for permission to run specific methods; instead, the container executes all of the EJB methods under the specified security identity. You can specify a particular role or the caller's identity as the security identity.

In an EJB 3.0 application, you can use annotations (see "Using Annotations").

In an EJB 3.0 or EJB 2.1 application, you can use the ejb-jar.xml deployment descriptor (see "Using Deployment XML").

Using Annotations

In an EJB 3.0 application, you can use the @RunAs annotation to specify the role of the application during execution in a J2EE container as Example 22-1 shows.

Example 22-3 @RunAs

@RunAs("Admin")
public class Calculator
{
    ...
}

You can apply this annotation to a class.

For more information on security annotations, see "Using EJB 3.0 Security Annotations".

Using Deployment XML

Specify the runAs security identity in the <security-identity> element, which is contained in the <enterprise-beans> section. The following XML demonstrates that the POMgr is the role under which all the entity bean methods execute.

<enterprise-beans>
  <entity>
  ... 
    <security-identity>
      <run-as>
        <role-name>POMgr</role-name>
      </run-as>
    </security-identity>
...
  </entity>
</enterprise-beans>

Alternatively, the following XML example demonstrates how to specify that all methods of the bean execute under the identity of the caller:

<enterprise-beans>
  <entity>
  ... 
    <security-identity>
      <use-caller-identity/>
    </security-identity>
...
  </entity>
</enterprise-beans>

Mapping Logical Roles to Users and Groups

You can use logical roles or actual users and groups in the EJB deployment descriptor. However, if you use logical roles, you must map them to the actual users and groups defined either in the OracleAS JAAS Provider or XML User Managers.

Map the logical roles defined in the application deployment descriptors to OracleAS JAAS Provider or XML User Manager users or groups through the <security-role-mapping> element in the OC4J-specific deployment descriptor.

  • The name attribute of this element defines the logical role that is to be mapped.

  • The group or user element maps the logical role to a group or user name. This group or user must be defined in the OracleAS JAAS Provider or XML User Manager configuration. See the Oracle Containers for J2EE Services Guide for a description of the OracleAS JAAS Provider and XML User Managers.

Example 22-4 Mapping Logical Role to Actual Role

This example maps the logical role POMGR to the managers group in the orion-ejb-jar.xml file. Any user that can log in as part of this group is considered to have the POMGR role; thus, it can execute the methods of PurchaseOrderBean.

<security-role-mapping name="POMGR"> 
 <group name="managers" /> 
</security-role-mapping> 

Note:

You can map a logical role to a single group or to several groups.

To map this role to a specific user, do the following:

<security-role-mapping name="POMGR"> 
 <user name="guest" /> 
</security-role-mapping> 

Lastly, you can map a role to a specific user within a specific group, as follows:

<security-role-mapping name="POMGR"> 
 <group name="managers" />
 <user name="guest" /> 
</security-role-mapping> 

As shown in Figure 22-3, the logical role name for POMGR defined in the EJB deployment descriptor is mapped to managers within the OC4J-specific deployment descriptor in the <security-role-mapping> element.

Figure 22-3 Security Mapping

Description of Figure 22-3 follows
Description of "Figure 22-3 Security Mapping"

Notice that the <role-name> in the EJB deployment descriptor is the same as the name attribute in the <security-role-mapping> element in the OC4J-specific deployment descriptor. This is what identifies the mapping.

Specifying a Default Role Mapping for Undefined Methods

If any methods have not been associated with a role mapping, they are mapped to the default security role through the <default-method-access> element in the orion-ejb-jar.xml file. The following is the automatic mapping for any insecure methods:

<default-method-access>
   <security-role-mapping name="&lt;default-ejb-caller-role&gt;"
                          impliesAll="true" >
   </security-role-mapping>
</default-method-access>

The default role is <default-ejb-caller-role> and is defined in the name attribute. You can replace this string with any name for the default role. The impliesAll attribute indicates whether any security role checking occurs for these methods. This attribute defaults to true, which states that no security role checking occurs for these methods. If you set this attribute to false, the container will check for this default role on these methods.

If the impliesAll attribute is false, you must map the default role defined in the name attribute to a OracleAS JAAS Provider or XML user or group through the <user> and <group> elements. The following example shows how all methods not associated with a method permission are mapped to the "others" group.

<default-method-access>
   <security-role-mapping name="default-role" impliesAll="false" >
      <group name="others" />
   </security-role-mapping>
</default-method-access>

Specifying Users and Groups by the Client

In order for the client to access methods that are protected by users and groups, the client must provide the correct user or group name with a password that the OracleAS JAAS Provider or XML User Manager recognizes. And the user or group must be the same one as designated in the security role for the intended method. See "Specifying Credentials in EJB Clients" for more information.


Note:

For basic OC4J security configuration information, including CSiV2, see the Oracle Containers for J2EE Security Guide.

Specifying Credentials in EJB Clients

Depending on the type of client, you may need to specify security credentials before your client can access an EJB or other JNDI-accessible resource.

Table 22-1 classifies EJB clients by where they are deployed relative to the target enterprise JavaBeans they invoke. Where you deploy the client relative to its target enterprise JavaBeans determines whether or not you must specify security credentials.

Table 22-1 Client Security Credential Requirements

Client Type Relationship to Target EJB Set Credentials?

Any client

Client and target EJB are collocated

No

Any client

Client and target EJB are deployed in the same application

No

Any client

Target EJB deployed in an application that is designated as the client's parentFoot 1 

No

Any client

Client and target EJB are not collocated, not deployed in the same application, and target EJB application is not client's parentFootref 1.

Yes


Footnote 1 See the Oracle Containers for J2EE Developer's Guide for more information on how to set the parent of an application.

When you access EJBs in a remote container (that is, if the client and target EJB are not collocated, not deployed in the same application, and the target EJB application is not the client's parent), you must pass valid credentials to the remote container. How your client passes its credentials depends on the type of client:

In addition, all clients can specify security properties in the ejb_sec.properties file (see "Specifying EJB Client Security Properties in the ejb_sec.properties File").

For more information, see:

Specifying Credentials in JNDI Properties

To specify credentials in a jndi.properties file:

  1. Create or modify an existing jndi.properties file.

  2. Configure the appropriate credentials in the jndi.properties file as Example 22-6 shows.

    For property names, see the field definitions in javax.naming.Context.

    Example 22-5 Specifying Credentials in JNDI Properties

    java.naming.security.principal=POMGR
    java.naming.security.credentials=welcome
    java.naming.factory.initial=
        oracle.j2ee.server.ApplicationClientInitialContextFactory
    java.naming.provider.url=opmn:ormi://opmnhost:6004:oc4j_inst1/ejbsamples
    
    
  3. Ensure that the jndi.properties file is on the client's classpath.

  4. Use the JNDI API in your client to look up the JNDI-accessible resource as Example 22-6 shows.

    Example 22-6 Looking Up a JNDI-Accessible Resource

    Context ic = new InitialContext();
    CustomerHome = (CustomerHome)ic.lookup("java:comp/env/purchaseOrderBean"); 
    
    

At runtime, JNDI uses ClassLoader method getResources to locate all application resource files named jndi.properties in the classpath. In doing so, it will use the JNDI properties you set in Example 22-6 to access the purchaseOrderBean.

For more information, see "Setting JNDI Properties with the JNDI Properties File".

Specifying Credentials in the Initial Context

To specify credentials in the initial context you use to look up JNDI-accessible resources:

  1. Create a HashTable and populate it with the required properties using javax.naming.Context fields as keys and String objects as values as Example 22-7 shows.

    Example 22-7 Specifying Credentials in the Initial Context

    Hashtable env = new Hashtable(); 
    env.put(Context.SECURITY_PRINCIPAL, "POMGR"); 
    env.put(Context.SECURITY_CREDENTIALS, "welcome"); 
    env.put("java.naming.factory.initial",
            "oracle.j2ee.server.ApplicationClientInitialContextFactory"); 
    env.put("java.naming.provider.url",
            "opmn:ormi://opmnhost:6004:oc4j_inst1/ejbsamples"); 
    
    
  2. When you instantiate the initial context, pass the HashTable into the initial context constructor as Example 22-8 shows.

    Example 22-8 Looking Up a JNDI-Accessible Resource

    Context ic = new InitialContext (env); 
    CustomerHome = (CustomerHome) ic.lookup ("java:comp/env/purchaseOrderBean");
    
    

For more information, see:

Specifying EJB Client Security Properties in the ejb_sec.properties File

Any client, whether running inside a server or not, has EJB security properties controlled by an ejb_sec.properties file. You use this file to specify general security options as well as options specific to the Common Secure Interoperability Version 2 protocol (CSIv2).

For more information, see "Common Secure Interoperability Protocol" in the Oracle Containers for J2EE Security Guide.

Using EJB 3.0 Security Annotations

In an EJB 3.0 application, you can use the javax.annotation.security annotations defined in JSR250 to configure security options on EJB 3.0 session beans.

Table 22-2 summarizes the security annotations that OC4J supports. For an example of how to use these annotations, see "Using Annotations".

Table 22-2 Security Annotations

Annotation Description Applicable To

@RunAs

Defines the role of the application during execution in a J2EE container. The role must map to the user/group information in the container's security realm.

For more information, see "Specifying the runAs Security Identity".

Class

@RolesAllowed

Specifies the security roles permitted to access methods in an application.

For more information, see "Specifying a Role for an EJB Method".

Class, method, or both.

Method specification overrides class specification if present.

@PermitAll

Specifies that all security roles are allowed to invoke the specified methods.

For more information, see "Specifying Unchecked Security for EJB Methods".

Class or method.

Class specification applies to all methods.

Method specification applies only to that method.

@DenyAll

Specifies that no security roles are allowed to invoke the specified methods.

Class or method.

Class specification applies to all methods.

Method specification applies only to that method.

@DeclareRoles

Specifies the security roles used by the application.

Class


When using @PermitAll, @DenyAll and @RolesAllowed annotations, observe the following restrictions:

Using Annotations

Example 22-9 shows how to use the @RolesAllowed annotation. For more information and examples, see the JSR250 specification.

Example 22-9 @RolesAllowed

@RolesAllowed("Users")
public class Calculator 
{
    @RolesAllowed("Administrator")
    public void setNewRate(int rate) 
    {
    ...
    }
}

Retrieving Credentials from an EJB Using the JAAS API

OC4J supports the use of standard JAAS API to retrieve the Subject, Principal, and credentials from within business methods and lifecycle methods of session beans (stateless and stateful) and entity beans.

Example 22-10 shows how you can use the JAAS API to retrieve credentials in a business method of an EJB deployed to OC4J.

Example 22-10 Using JAAS API to Retrieve Credentials

public class Calculator
{
    // Buisness method
    public void setNewRate(int rate)
    {
    ...
        AccessControlContext actx = AccessController.getContext();
        Subject subject = Subject.getSubject(actx);
        Set principals = subject.getPrincipals();
    ...
    }
}

Defining a Custom JAAS Login Module for an EJB Application

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 the subject. Possible types of JAAS login modules include a principal-mapping JAAS module, a credential-mapping JAAS module, a Kerberos JAAS module, or a custom login module.

Before you can use a custom JAAS login module with your EJBs, you must configure the following in the orion-application.xml file:

For more information, see "Login Modules" in the Oracle Containers for J2EE Security Guide.