Standard Programmatic EJB Access Controls
Although the programmatic implementation of security access-control logic within EJB components is not recommended by the EJB specification, it could be inevitable in many practical cases. 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 2, two primary EJB 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 depreciated). Other nonsecurity-related EJBContext methods are not shown in this figure.
Figure 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 on a bean instance after the bean instance is created by the container.
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 business-specific security-checking logic decision making.
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 acting in this role.
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, which, in turn, is defined within an outermost <ejb-jar> element inside the standard ejb-jar.xml file.
As an example, if we have defined a standard ejb-jar.xml file for an OrderManager session bean that implements the getOrder() method defined previously, then we would want to 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.// [ic:ccc]DTD Enterprise JavaBeans 1.1//EN' [ic:ccc] '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 the 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.