Chapter 14. Enterprise JavaBeans Security

Java 2 Platform, Enterprise Edition (J2EE)-compliant Enterprise JavaBeans (EJB) provides a model for developing server-side enterprise application components that can make building portable and distributed enterprise applications easier than building standalone enterprise applications. EJB containers/servers provide distributed communications services, data-enabling services, and systems assurance services for EJB components. These services require minimal effort on the part of a developer.

Standard security assurance is primarily provided in the form of role-based access control to EJBs. Vendor-specific support is also needed to map the roles defined using standard mechanisms to principals managed by a particular EJB container/server vendor's operational environment. Additionally, vendor-specific and/or hand-coded mechanisms are needed to provide any necessary authentication, identity delegation policy selection, secure communications, and auditing. This chapter will describe the standard mechanisms provided for J2EE-compliant EJBs and outline those vendor-specific or hand-coded mechanisms that must be provided to fully secure your EJBs.

In this chapter, you will learn

  • A basic overview of the options available for securing your EJBs

  • The standard programmatic access control mechanisms available for EJBs

  • The standard declarative access control mechanisms available for EJBs

  • The most common vendor-specific access control mechanisms available for EJBs

  • The most common vendor-specific identity and authentication mechanisms available for EJBs

  • A basic overview of the additional vendor-specific mechanisms available for providing secure EJB communications, principal delegation, and auditing

EJB Security Overview

As with any distributed object used in security-critical enterprise applications, EJBs must be secured. However, EJB components operate inside a container environment and rely on the container to provide distributed connectivity to an EJB, to create and destroy EJB instances, to passivate and activate EJB instances, to invoke business methods on EJBs, and to generally manage the life cycle of an EJB. Because such control is relinquished to an EJB container/server environment, securing the EJB also relies heavily on the support provided by the EJB container environment. Security mechanisms can distinguish between standard mechanisms required by the J2EE and EJB specifications, mechanisms that are EJB container/server vendor-specific, and mechanisms that can be hand-coded by the EJB developer.

Figure 14.1 illustrates the basic architecture required for securing EJBs. Standard security mechanisms defined for EJBs are currently focused around providing a minimal set of constructs for role-based EJB access control. Standard mechanisms for determining role-based permissions to access EJB methods can be tapped by EJB components programmatically via a few interfaces to the EJB container context, as exposed by the EJB API. Standard EJB method access control mechanisms can also be defined declaratively via a set of standard XML elements contained in a standard EJB deployment descriptor. Additionally, a few vendor-specific access control features are needed to support the mapping of security roles defined in standard deployment descriptors to principal identities managed by the operational environment.

EJB security architecture.

Figure 14.1. EJB security architecture.

Although a mechanism for authenticating a user is implied by the fact that a particular user must be granted access to a particular EJB method, no standard means for authenticating a user is defined in the EJB v1.1 and the J2EE v1.2 specifications. Such standard mechanisms are planned for the J2EE v1.3 and EJB 2.0, however. It is anticipated that the Java Authentication and Authorization Standard (JAAS) will play a key role in determining how principals are authenticated. Nevertheless, some form of identity propagation from client to server, and principal authentication with an identity repository must be provided by an EJB container/server vendor for practical EJB enterprise security. The policy for delegating principal identity between EJBs must also be defined by an EJB container/server vendor. Furthermore, the security of the communications session between EJB client and server must be provided by a vendor for practical enterprise deployment scenarios. Vendors can also provide a means for auditing security-critical EJB events.

Standard Programmatic EJB Access Controls

Although the programmatic implementation of security access control logic within EJB components is not recommended by the EJB specification, in many practical cases, it is inevitable. A minimal set of standard methods is provided by the EJB API to enable programmatic access control from within your EJB. As illustrated in Figure 14.2, two primary EJB v1.1 hooks for obtaining security information from the EJB container environment are provided by the javax.ejb.EJBContext object (and two other EJB v1.0 methods are deprecated). Other nonsecurity related EJBContext methods are not shown in this diagram.

EJB security APIs.

Figure 14.2. EJB security APIs.

A handle to an EJBContext object is available to an EJB implementation object when the EJB container sets the context object onto a bean instance after the bean instance has been created by the container. For session bean implementations, such as MySessionBean shown in Figure 14.2, the EJB container calls setSessionContext() on the bean with a javax.ejb.SessionContext object. For entity bean implementations, such as MyEntityBean shown in Figure 14.2, the EJB container calls setEntityContext() on the bean with a javax.ejb.EntityContext object. After a context is set onto a bean, security-related calls to the EJBContext object are callable only from within the context of a business-specific method on the EJB. Otherwise, a java.lang.IllegalStateException will be thrown by the container to indicate that no security context exists.

The EJBContext.getCallerPrincipal() method is invoked by an EJB to obtain a handle to a java.security.Principal object. The Principal represents the particular principal identity on behalf of which the invoking EJB client is acting. A call to Principal.getName() by the bean can return a String object that can be used for implementing business-specific security-checking logic. The deprecated EJBContext.getCallerIdentity() method might still be supported by your container, but a vendor might choose to throw an exception or return null from this method.

The EJBContext.isCallerInRole(String) method is used to ask the EJB environment whether the current principal associated with this security context is a member of the role passed in as a String to this method. A Boolean return value indicates whether the caller is indeed in this role. The deprecated EJBContext.isCallerInRole(Identity) method might still be supported by your container, but a vendor might choose to throw an exception from this method.

For example, you might have an EJB that allows a client to retrieve sensitive customer-order data given a customer ID. You might restrict such access only to authorized users in the admin role or to the particular customer having that customer ID as a principal name, as shown here:

public Order getOrder(String customerID) throws OrderException
{
    // Declare some application-specific Order object to return
    Order returnOrder = null;

    // Get principal from context and principal name
    java.security.Principal caller = ejbContext.getCallerPrincipal();
    String callerID = caller.getName();

    // If not in admin role and not the user associated with
    //   this order, then deny access...
    if(   (ejbContext.isCallerInRole("admin") == true)
        ||(callerID.equalsIgnoreCase(customerID)     ))
    {
      // Allow access to do security-critical stuff here...
        ...
    }
    else
    {
      // Access denied. Audit this event and return...
        ...
      // Throw some application-specific OrderException
      throw new OrderException("Order retrieval access denied.");
    }

    // Return the application-specific Order object
    return returnOrder;
}

Whenever a call to EJBContext.isCallerInRole() is made from within EJB code, an associated <security-role-ref> should be identified in the EJB's standard deployment descriptor for that bean. The <security-role-ref> element is defined within an <entity> element for entity beans and within a <session> element for session beans. The <entity> and <session> elements are defined within an <enterprise-beans> element that, in turn, is defined within an outer most <ejb-jar> element inside of the standard ejb-jar.xml file.

For example, you might define a standard ejb-jar.xml file for an OrderManager session bean that implements the getOrder() method defined earlier. Next, you define a <security-role-ref> entry for the referenced admin role as follows:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE ejb-jar PUBLIC '-//Sun Microsystems, Inc.//×DTD Enterprise JavaBeans 1.1//EN'×
EJB security APIs. 'http://java.sun.com/j2ee/dtds/ejb-jar_1_1.dtd'>
<ejb-jar>
    ...
  <enterprise-beans>
    <session>
        ...   
      <!-- EJB Reference name for our bean -->
      <ejb-name>OrderManager</ejb-name>
      <!-- Class name for our EJB Home interface -->
      <home>ejava.ejbsecurity.OrderManagerHome</home>
      <!-- Class name for our EJB Remote interface -->
      <remote>ejava.ejbsecurity.OrderManager</remote>
      <!-- Class name for our EJB implementation -->
      <ejb-class>ejava.ejbsecurity.OrderManagerBean</ejb-class>
        ...
      <!-- Identifies a security role reference for this EJB.-->
      <security-role-ref>

        <!-- Describes this security role. -->
        <description> Bean references admin role. </description>

        <!-- Identifies a logical role name that this EJB uses. -->
        <role-name>admin</role-name>

      </security-role-ref>

    </session>

  </enterprise-beans>
</ejb-jar>

It is the responsibility of EJB developers to define, in a deployment descriptor, those security roles that their EJB implementations programmatically reference. However, it is up to the EJB assembler and deployer to map such roles to security roles and users in the deployment environment. The next section illustrates how such a mapping occurs in the context of standard declarative EJB access controls.

Standard Declarative EJB Access Controls

Standard declarative EJB access control mechanisms are defined as XML elements in a standard EJB deployment descriptor file. In addition to the <role-name> element, a <role-link> element can also be defined within an EJB's <security-role-ref> element. This element value is defined during EJB assembly to reference a role name specified by an individual (an EJB assembler) cognizant of the security roles assumed by a particular deployment environment. Thus, an EJB assembler might modify the standard ejb-jar.xml file to map a programmatic role name identified by the <role-name> element to an assembly-specific role name identified by a <role-link> element.

You can, for example, modify the OrderManager deployment descriptor to incorporate an assembly-specific <role-link> element as follows:

<?xml version="1.0" encoding="UTF-8"?>
  ...
<ejb-jar>
    ...
  <enterprise-beans>
    <session>
        ...   
       <!-- Identifies a security role reference for this EJB.-->
      <security-role-ref>

        <!-- Describes this security role. -->
        <description> Bean references admin role. </description>

        <!-- Identifies a logical role name that this EJB uses. -->
        <role-name>admin</role-name>

        <!-- Identifies a role to map to during assembly. -->
        <role-link>Administrator</role-link>

      </security-role-ref>

    </session>

  </enterprise-beans>
</ejb-jar>

The <role-link> element must refer to a <role-name> defined within a special <security-role> element defined by an EJB assembler in the standard ejb-jar.xml file. All logical security roles defined for a particular EJB module are identified by <security-role> elements that sit within an <assembly-descriptor> element that is defined within the root <ejb-jar> element for an EJB module.

For example, an EJB assembler might define a <security-role> element for the Administrator role linked by the OrderManager bean as well as a RegisteredCustomer and UnregisteredCustomer role as follows:

<?xml version="1.0" encoding="UTF-8"?>
  ...
<ejb-jar>
    ...
  <enterprise-beans>
    ...
  </enterprise-beans>
  <assembly-descriptor>
    <!-- Identifies those security roles defined for an EJB module.-->
    <security-role>
      <!-- Describes a security role. -->
      <description> Administrator role for bean. </description>
      <!-- Identifies a logical role name that this EJB module uses. -->
      <role-name>Administrator</role-name>
    </security-role>

    <!-- Identifies those security roles defined for an EJB module.-->
    <security-role>
      <!-- Describes a security role. -->
      <description> Registered customer role for bean. </description>
      <!-- Identifies a logical role name that this EJB module uses. -->
      <role-name>RegisteredCustomer</role-name>
    </security-role>

    <!-- Identifies those security roles defined for an EJB module.-->
    <security-role>
      <!-- Describes a security role. -->
      <description> Unregistered customer role for bean. </description>
      <!-- Identifies a logical role name that this EJB module uses. -->
      <role-name>UnregisteredCustomer</role-name>
    </security-role>
       ...
  </assembly-descriptor>

</ejb-jar>

Special deployment descriptor elements can also be defined that dictate those security roles that can access particular methods on an EJB. Zero or more <method-permission> elements defined within an <assembly-descriptor> element are used to provide such role-to-method access control mappings. A <method-permission> element can contain a <description> element, one or more <role-name> elements, and one or more <method> elements. The <role-name> elements simply contain role name values that have been defined in a <role-name> element contained by the <security-role> elements defined previously. The <method> element identifies particular EJB method(s) for which this access control specification applies. A <method> element in turn can contain the following elements:

  • <description>: The <description> element can optionally be used to describe the EJB method access control mapping.

  • <ejb-name>: The <ejb-name> element identifies the EJB reference name to which this specification applies.

  • <method-intf>: The <method-intf> element optionally specifies if the home or remote interface applies to this particular method specification. The values of Home or Remote are used. This element is of use when EJB home and remote interfaces have identical method names, and you need to differentiate between the two types.

  • <method-name>: The <method-name> element identifies the EJB method(s) to which this mapping applies. A name can be used here to define a specific method name. Alternatively, if an asterisk (*) is used, this particular mapping applies to all methods on the EJB.

  • <method-params>: The <method-params> element is used to specify fully qualified parameter types associated with an EJB method to which this mapping applies. The <method-params> element can contain zero or more <method-param> elements that are associated with fully qualified class type names. The <method-params> element information uniquely identifies a particular EJB method according to its parameter types and overrides any generic specification for a particular group of overloaded methods or for the whole EJB.

For example, you might have defined the following additional methods on an OrderManager bean for which you want a container to manage secure access control:

public void makeOrder(String orderID)
    {  /* Do something...*/ }
public void makeOrder(String orderID, String customerID)
    {  /* Do something...*/ }
public void makeOrder(String orderID, String customerID, Vector items)
    { /* Do something...*/ }

public void cancelOrders(String customerID)
    {  /* Do something...*/  }
public void cancelOrders(String customerID, Vector items)
    {  /* Do something...*/ }

Now suppose that during assembly time, you decide the following about this bean's secure access control semantics:

  • All remote methods should allow Administrator role access by default.

  • The previously defined getOrder() method should also allow RegisteredCustomer role access.

  • Both remote cancelOrders() methods should also allow RegisteredCustomer role access.

  • The remote makeOrder(String, String) and makeOrder(String, String, Vector) method should also allow UnregisteredCustomer and RegisteredCustomer role access.

Given such security access role semantics, you can define your ejb-jar.xml file for this bean using the <method-permission> elements shown here:

<?xml version="1.0" encoding="UTF-8"?>
  ...
<ejb-jar>
    ...
  <enterprise-beans>
    <session>
        ...
      <!-- EJB Reference name for our bean -->
      <ejb-name>OrderManager</ejb-name>
      <!-- Class name for our EJB Home interface -->
      <home>ejava.ejbsecurity.OrderManagerHome</home>
      <!-- Class name for our EJB Remote interface -->
      <remote>ejava.ejbsecurity.OrderManager</remote>
      <!-- Class name for our EJB implementation -->
      <ejb-class>ejava.ejbsecurity.OrderManagerBean</ejb-class>
        ...  
    </session>
      ...
  </enterprise-beans>

  <assembly-descriptor>
      ...
    <!-- Define Administrator access. -->
    <method-permission>
      <description>
        Administrator access control for the OrderManager bean.
        Will allow access to all methods on OrderManager.
      </description>
      <role-name>Administrator</role-name>
      <method>
        <ejb-name>OrderManager</ejb-name>
        <method-name>*</method-name>
      </method>
    </method-permission>

    <!-- Add access on getOrder to RegisteredCustomer. -->
    <method-permission>
      <description>
        RegisteredCustomer access control for access to the
        OrderManager getOrder() method.
      </description>
      <role-name>RegisteredCustomer</role-name>
      <method>
        <ejb-name>OrderManager</ejb-name>
        <method-intf>Remote</method-intf>
        <method-name>getOrder</method-name>
      </method>
    </method-permission>

    <!-- Add access on cancelOrders to RegisteredCustomer. -->
    <method-permission>
      <description>
        RegisteredCustomer access control for access to the
        OrderManager cancelOrders() methods.
      </description>
      <role-name>RegisteredCustomer</role-name>
      <method>
        <ejb-name>OrderManager</ejb-name>
        <method-intf>Remote</method-intf>
        <method-name>cancelOrders</method-name>
      </method>
    </method-permission>

    <!-- Add access to specific makeOrder methods. -->
    <method-permission>
      <description>
        RegisteredCustomer access control for access to the
        OrderManager makeOrder(String, String) and the
        makeOrder(String, String, Vector) methods.
      </description>
      <role-name>UnregisteredCustomer</role-name>
      <role-name>RegisteredCustomer</role-name>
      <method>
        <ejb-name>OrderManager</ejb-name>
        <method-intf>Remote</method-intf>
        <method-name>makeOrder</method-name>
        <method-params>
          <method-param>java.lang. String</method-param>
          <method-param>java.lang.String</method-param>
        </method-params>
      </method>
      <method>
        <ejb-name>OrderManager</ejb-name>
        <method-intf>Remote</method-intf>
        <method-name>makeOrder</method-name>
        <method-params>
          <method-param>java.lang.String</method-param>
          <method-param>java.lang.String</method-param>
          <method-param>java.util.Vector</method-param>
        </method-params>
      </method>
    </method-permission>

  </assembly-descriptor>

</ejb-jar>

Vendor-Specific EJB Access Controls

Although the roles specified by an assembler in the <security-role> elements of an ejb-jar.xml file define logical roles assumed by an EJB application, the container and EJB deployers must map these roles to actual user groups and/or to users in the operational system. Additionally, the container and EJB deployers must manage how these roles relate to particular security domains from the operational system. Vendor-specific mappings from logical security role to operational environment groups/users can be performed in an automated fashion without requiring the development of vendor-specific code.

An example of a vendor-specific mapping tool is the DeployerTool, a GUI tool that comes with the BEA WebLogic Server. The DeployerTool can be used to map standard J2EE EJB defined role names to principal names that have meaning in an operational BEA WebLogic Server environment. After selecting a particular WebLogic Server, an EJB deployer loads a particular EJB module stored in a JAR file. After selecting the particular bean whose security profile will be mapped, you select a Security item in the GUI for that bean. The standard EJB security application roles that were stored in <security-role> elements for that module are then be displayed. The GUI also displays those principal names available to the BEA WebLogic Server environment. (Exactly how such principal names are made available will be described in the next section.) The GUI tool then allows you to see what principal names are currently mapped to those standard roles. You can also add and delete principal associations with those roles.

When performing such a mapping, the DeployerTool populates a vendor-specific weblogic-ejb-jar.xml file. The weblogic-ejb-jar.xml file contains zero or more <security-role-assignment> elements containing a standard EJB <role-name> element that maps to one or more WebLogic-specific <principal-name> elements. For example, you might specify that your standard Administrator role name maps to a root and sysop user in an operational WebLogic Server environment and yields the following weblogic-ejb-jar.xml file:

<?xml version="1.0"?>

<!DOCTYPE weblogic-ejb-jar PUBLIC '-//BEA Systems, Inc.//×DTD WebLogic 5.1.0 EJB//EN'×
Vendor-Specific EJB Access Controls 'http://www.beasys.com/j2ee/dtds/weblogic-ejb-jar.dtd'>

<weblogic-ejb-jar>
  <weblogic-enterprise-bean>
      ...
  </weblogic-enterprise-bean>
   ...
  <security-role-assignment>
    <role-name>Administrator</role-name>
    <principal-name>root</principal-name>
    <principal-name>sysop</principal-name>
  </security-role-assignment>
    ...
</weblogic-ejb-jar>

Such declarative EJB security access control checking mechanisms provide a codeless way for determining whether a particular user in a particular role is allowed access to a particular method on a particular EJB. However, some enterprise applications might need to provide access control checking functionality in which access to a particular EJB method is allowed based on some business-specific state and logic of the system associated with that user. For example, it might not be valid to say that all users belonging to a particular employee role have access or do not have access to particular getter and setter methods on some TimeSheet EJB that encapsulates employee timesheets in an enterprise human resource management application. Rather, you might implement a security-checking mechanism that provides access control to such TimeSheet EJB getter and setter methods based on whether the identity of the invoking client matches some employeeID field state of the TimeSheet EJB. Although bean developers can use the standard programmatic EJB access control checking mechanisms to implement the needed logic, some EJB container vendors provide additional access control mechanisms to implement such features.

Vendor-Specific EJB Identity and Authentication

Vendor-specific mappings, from logical security role to operational environment groups/users, might not require any vendor-specific code, but the exact means by which your container manages the access, addition, and removal of the operational groups/users within its auspices might indeed require vendor-specific code. You saw the vendor-specific means for mapping standard EJB security roles to principal names in the last section. But how do you customize your vendor's server environment to be cognizant of such valid principal names? For example, if your enterprise manages principal information in a database, a vendor-specific means to access that information via custom JDBC calls might be required. However, you might also decide to use whatever means are provided by your particular vendor to automatically manage such information, which might not require specialized coding. Such methods might, instead, include a means to specify principal information in a simple text file, an XML file, or an LDAP structure.

The BEA WebLogic Server, in fact, uses a text-based configuration file (that is, its weblogic.properties file) as the default means for storing usernames and passwords. User information is added to this file in the form of name/value entries as follows:

weblogic.password.userName=userPassword
					

Similarly, groups can be added to the file in the following form:

weblogic.security.group.groupName=userName1,userName2,userName3,...

Configuring principal information using static configuration files, however, is infeasible for most medium-to-large-scale applications. Thus, BEA WebLogic also provides a means to manage identities stored in alternative principal identification repositories (security domains or realms). An alternate realm is designated in the weblogic.properties file by setting a special weblogic.security.RealmClass property equal to a fully qualified class name encapsulating the alternative realm. Such classes implement WebLogic-specific interfaces that enable the WebLogic server environment to invoke operations on such class instances during operational processing of security-related events. The available alternative BEA WebLogic v5.1 realm types include

  • LDAP Realm: . Enables the authentication of principals managed in a Lightweight Directory Access Protocol (LDAP) server. The weblogic.security.ldaprealm.LDAPRealm class must be referenced in the weblogic.properties file by the weblogic.security.RealmClass property. You must also edit a special WebLogic ldaprealm.properties file containing a number of LDAP-specific properties that must be edited for your environment.

  • Windows NT Realm: . Enables the authentication of principals managed in a Windows NT security domain. The weblogic.security.ntrealm.NTRealm class must be referenced in the weblogic.properties file by the weblogic.security.RealmClass property. A special WebLogic ntrealm.properties file's weblogic.security.ntrealm.domain property must also contain a reference to the primary Windows NT domain controller host name.

  • UNIX Realm: . Enables the authentication of principals managed in a UNIX security domain. The weblogic.security.unixrealm.UnixRealm class must be referenced in the weblogic.properties file by the weblogic.security.RealmClass property. You must also configure your system for use of a special WebLogic wlauth program that looks up users and groups from the UNIX security domain.

  • Database Realm: . Enables the authentication of principals whose information is stored in a database. WebLogic supplies an examples.security.rdbmsrealm.RDBMSRealm class that can be used as a template for your database-specific custom-realm management. The sample class can also be referenced directly in the weblogic.properties file by the weblogic.security.RealmClass property. A special rdbmsrealm.properties file can then be configured with your RDBMS's particular database connection information and principal-management-related database SQL queries.

If none of the principal information management realms that come equipped with BEA WebLogic satisfy your needs out of the box, you can create your own custom realm following the pattern of the RDBMSRealm class described earlier. A custom extendable identity management realm, however, involves the implementation of vendor-specific interfaces to support interoperation with the WebLogic security-checking environment. The basic approach is to create a special realm class that implements methods to retrieve and modify user, group, and access control information. Thus, user profile information can be stored in a repository of your choice and managed in a business-specific fashion by these interface implementations. Your operational environment-specific implementations of these interfaces are based entirely on vendor-specific interfaces. However, such built-in support provides a lot of flexibility for managing your specific operational user profiles. Furthermore, a proper design pattern implementation can be used to isolate vendor-specific library dependencies from your business-specific logic.

Future EJB and J2EE specifications will most likely incorporate JAAS for standard authentication within EJB servers. In the meantime, you'll have to rely on utilizing vendor-specific means for authenticating clients in EJB server environments. A principal identity name and set of credentials must somehow propagate from EJB client to EJB server for authentication to occur. BEA WebLogic accomplishes this by setting the javax.naming.Context.SECURITY_PRINCIPAL and javax.naming.Context.SECURITY_ CREDENTIALS properties onto a javax.naming.InitialContext during initial connectivity with the EJB server from the client.

For example, the EJB client using the BEA WebLogic Server wishes access to the previously secured OrderManager EJB. The client passes username and credential information to the EJB server when obtaining an initial Java Naming and Directory Interface (JNDI) context as follows (excluding exception handling):

// Create properties that we'll use to connect with EJB server
Hashtable props = new Hashtable();
props.put(javax.naming.Context.PROVIDER_URL, "t3://localhost:7001/");
props.put(javax.naming.Context.INITIAL_CONTEXT_FACTORY,
            "weblogic.jndi.WLInitialContextFactory");
props.put(javax.naming.Context.SECURITY_PRINCIPAL, "root");
props.put(javax.naming.Context.SECURITY_CREDENTIALS, "turnthetheta");

// Get initial context for standalone client using properties
Context context = new InitialContext(props);

On the BEA WebLogic server side, if a custom realm is being used, special callbacks onto the custom realm implementation class are made to pass such principal and credential information enabling your code to provide custom authentication of such users with the system. A vendor-specific object (weblogic.security.acl.User) returned by your custom realm code to the WebLogic container representing an authenticated user of the system is then associated with a server-side thread handler for the client. When subsequent requests are made from that same client associated with the thread, the client's credentials from its thread handler can be used in the process of providing access control for EJBs.

Thus, if the EJB client previously authenticated during an initial JNDI context creation operation can access the system, it might attempt to lookup EJB home references and invoke operations on those EJBs as usual. If an EJB's methods have been restricted using the standard and vendor-specific access control mechanisms defined previously, the security-critical EJB operations will be checked by the server during runtime operation. For example, if your EJB client now wishes to make a security-critical getOrder() call onto your OrderManager EJB defined earlier, you might have the following code (excluding exception handling):

// Look up server reference using raw JNDI name
Object object = context.lookup("OrderManagerHome");

// Narrow to order manager reference
OrderManagerHome orderManagerHome = (OrderManagerHome)
   PortableRemoteObject.narrow(object,
      ejava.ejbsecurity.OrderManagerHome.class);

// Create handle to server object now using home factory
OrderManager mgr = orderManagerHome.create();

// Now make a security-critical EJB call
Order order = mgr.getOrder("joeShmoe");

The OrderManager.getOrder() call can be successfully invoked in the preceding example because this EJB client logged in as a root user, you have mapped the root user to the Administrator role, and the Administrator role has been granted access to this EJB method.

EJB Secure Communications, Delegation, and Auditing

Thus far, I have covered EJB access control, secure identity propagation, and authentication. You must consider a few additional issues, however, before deploying your security-critical EJBs into an operational enterprise environment. For one, the connection between your EJB clients and servers must often be secured in some fashion. The means by which principal identity is delegated and the mechanisms for auditing security-critical events must also be taken into consideration. This section closes the chapter with a discussion of those vendor-specific mechanisms that must be provided to support such concerns.

EJB Connection Security

The EJB client authentication sequence defined in the previous section passes user credential information into a JNDI context object with no guarantee about the secured nature of the client-to-server connection. Thus, the client's credential information might very well have been transferred to the server in the clear. For certain types of EJB clients and application scenarios, this might be acceptable. For example, if the EJB client is a Java Servlet or JavaServer Page, and if the Web server sits behind the same trusted computing base and firewall as the EJB application server, this situation might be acceptable. However, for most enterprise applications, the connection between EJB client and EJB server needs to operate over some secured socket mechanism.

The J2EE v1.2 and EJB v1.1 specifications do not specify any standard means for securing such connections. Securing the EJB client-to-server connection is left up to your particular vendor's product implementation. The BEA WebLogic Server uses SSL with certificate credentials passed over the initial connection made with the server via JNDI. Although X509 certificates can be put into the Hashtable object passed to an InitialContext object constructor, you must also pass a username and optional password into the Hashtable. As described previously, the username will enable the WebLogic Server to identify the principal name associated with the certificate.

Such vendor-specific mechanisms also require additional identification and authentication handling logic to enable you to map between certificates and principal identity on the server side. Again, this logic might be provided to you in a vendor-specific fashion, or you can elect to implement your own hand-coded mechanisms (which will inevitably require hooking into vendor-specific features). Future EJB and J2EE specifications are expected to define more rigorous identity and authentication standard mechanisms, which will naturally incorporate standard means for ensuring secure EJB client-to-server communications.

EJB Principal Delegation

The default means for propagating principal identity should allow principal identity to propagate from one EJB to another. Thus, in a chain of calls made from one EJB to another, the principal identity associated with the original EJB client that initiated the call sequence will be propagated. Exactly how principal identity is propagated from the initial EJB client to the EJB server is left up to the vendor. If more than one option is provided, the vendor, of course, should provide a means during deployment for selecting the identity propagation policy to be employed. As a minimum requirement, the EJB client's principal identity used to connect to the EJB server can be used as the principal identity to be delegated to other EJBs within the EJB server environment.

EJB Security Auditing

EJB server vendors can also provide a means for auditing security-critical events. Security- critical events include logging the generation of any java.security.Exception exceptions, successful and failed authentication attempts, and failed EJB access attempts. The BEA WebLogic Server, for example, enables you to implement a vendor-specific AuditProvider auditing class. A special weblogic.security.audit.AuditProvider property in the weblogic.properties file must then be set to this class name. The WebLogic server will invoke methods on this class when an attempted authentication occurs, an authorization request is made, or an invalid user certificate is propagated to the server.

Summary

The standard provisions for EJB security focus on minimal programmatic and declarative access control mechanisms. Such mechanisms provide role-based access control for your EJBs. Nevertheless, a particular EJB container/server vendor must still provide a means to map such roles to principal names managed by a particular operational environment. Support for authentication, identity propagation, and identity delegation must be provided by your particular EJB container/server vendor. Furthermore, a vendor must also provide any means for secure communications between EJB client and server, as well as any means for security auditing. Thus, the J2EE v1.2 and EJB v1.2 specifications provide EJB developers with minimal, standard security-provisioning options. Future J2EE and EJB specifications are expected to incorporate JAAS into the mix for securing EJBs with authentication and authorization provided in a standards-based fashion.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.222.138.230