Enterprise Bean Example Applications
The following example applications demonstrate adding security to enterprise beans applications:
- Example: Securing an Enterprise Bean demonstrates adding basic login authentication to an enterprise bean application.
- Example: Using isCallerInRole and getCallerPrincipal demonstrates the use of the
getCallerPrincipal()
andisCallerInRole(String role)
methods.- Discussion: Securing the Duke's Bank Example provides a brief discussion of how the Duke's Bank example provides security in that application.
Example: Securing an Enterprise Bean
In this section, we discuss how to configure an enterprise bean for username-password authentication. When a bean that is constrained by username-password authenticationis requested, the server requests a user name and password from the client and verifies that the user name and password are valid by comparing them against a database of authorized users on the Application Server.
If the topic of authentication is new to you, please refer to the section titled Specifying an Authentication Mechanism (page 968).
For this tutorial, we will add the security elements to an enterprise bean; build, package, and deploy the application; and then build and run the client application.
The completed version of this example can be found at
<
INSTALL
>/javaeetutorial5/examples/ejb/cart-secure
. This example was developed by starting with the unsecured enterprise bean application,cart
, which is found in the directory<
INSTALL
>/javaeetutorial5/examples/ejb/cart
and is discussed in The cart Example (page 747). We build on this example by adding the necessary elements to secure the application using username-password authentication.In general, the following steps are necessary to add username-password authentication to an enterprise bean. In the example application included with this tutorial, many of these steps have been completed for you and are listed here simply to show what needs to be done should you wish to create a similar application.
- Create an application like the one in The cart Example (page 747). The example in this tutorial starts with this example and demonstrates adding basic authentication of the client to this application. The example application discussed in this section can be found at
<
INSTALL
>/javaeetutorial5/examples/ejb/cart-secure/
.- If you have not already done so, specify properties specific to your installation in the
<
INSTALL
>/javaeetutorial5/examples/bp-project/build.properties
file and the<
INSTALL
>/javaeetutorial5/examples/common/admin-password.txt
file. See Building the Examples (page xxxi) for information on which properties need to be set in which files.- If you have not already done so, add a user to the
file
realm and specifyuser
for the group of this new user. Write down the user name and password so that you can use them for testing this application in a later step. Refer to the section Managing Users and Groups on the Application Server (page 879) for instructions on completing this step.- Modify the source code for the enterprise bean,
CartBean.java
, to specify which roles are authorized to access protected methods. This step is discussed in Annotating the Bean.- Modify the runtime deployment descriptor,
sun-ejb-jar.xml
, to map the role used in this application (CartUser
) to a group defined on the Application Server (user
) and to add security elements that specify that username-password authentication is to be performed. This step is discussed in Setting Runtime Properties.- Build, package, and deploy the enterprise bean, then build and run the client application. See Building and Running the Example.
Annotating the Bean
The source code for the original
/cart
application was modified as shown in the following code snippet (modifications inbold
, method details removed to save paper). The resulting file can be found in<
INSTALL
>/javaeetutorial5/examples/ejb/cart-secure/cart-secure-ejb/src/java/cart/secure/ejb/CartBean.java
.package com.sun.tutorial.javaee.ejb; import java.util.ArrayList; import java.util.List; import javax.ejb.Remove; import javax.ejb.Stateful;import javax.annotation.security.RolesAllowed;
@Stateful() public class CartBean implements Cart { String customerName; String customerId; List<String> contents; public void initialize(String person) throws BookException { ... } public void initialize(String person, String id) throws BookException { ... }@RolesAllowed("CartUser")
public void addBook(String title) { contents.add(title); }@RolesAllowed("CartUser")
public void removeBook(String title) throws BookException { ... } }@RolesAllowed("CartUser")
public List<String> getContents() { return contents; } @Remove() public void remove() { contents = null; } }The
@RolesAllowed
annotation is specified on methods for which we want to restrict access. In this example, only users in the role ofCartUser
will be allowed to add and remove books from the cart, and to list the contents of the cart. An@RolesAllowed
annotation implicitly declares a role that will be referenced in the application, therefore, no@DeclareRoles
annotation is required.Setting Runtime Properties
The role of
CartUser
has been defined for this application, but there is no group ofCartUser
defined for the Application Server. To map the role that is defined for the application (CartUser
) to a group that is defined on the Application Server(user
), add a<security-role-mapping>
element to the runtime deployment descriptor,sun-ejb-jar.xml
, as shown below. In the original example, there was no need for this deployment descriptor, so it has been added for this example.To enable username-password authentication for the application, add security elements to the runtime deployment descriptor,
sun-ejb-jar.xml
. The security element that needs to be added to the deployment descriptor is the <ior-security-config
> element. The deployment descriptor is located in<
INSTALL
>/javaeetutorial5/examples/ejb/cart-secure/cart-secure-ejb/src/conf/sun-ejb-jar.xml
.<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE sun-ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Application Server 9.0 EJB 3.0//EN" "http://www.sun.com/software/appserver/dtds/sun-ejb-jar_3_0-0.dtd"> <sun-ejb-jar> <security-role-mapping> <role-name>CartUser</role-name> <group-name>user</group-name> </security-role-mapping> <enterprise-beans> <unique-id>0</unique-id> <ejb> <ejb-name>CartBean</ejb-name> <jndi-name>jacc_mr_CartBean</jndi-name> <pass-by-reference>false</pass-by-reference> <ior-security-config> <transport-config> <integrity>supported</integrity> <confidentiality>supported</confidentiality> <establish-trust-in-target>supported</establish-trust-in-target> <establish-trust-in-client>supported</establish-trust-in-client> </transport-config> <as-context> <auth-method>username_password</auth-method> <realm>default</realm> <required>true</required> </as-context> <sas-context> <caller-propagation>supported</caller-propagation> </sas-context> </ior-security-config> <is-read-only-bean>false</is-read-only-bean> <refresh-period-in-seconds>-1</refresh-period-in-seconds> <gen-classes/> </ejb> </enterprise-beans> </sun-ejb-jar>For more information, read Specifying an Authentication Mechanism and Configuring IOR Security.
Building and Running the Example
To build and run the
ejb/cart-secure
example, follow these steps.
- If you have not already done so, specify properties specific to your installation in the
<
INSTALL
>/javaeetutorial5/examples/bp-project/build.properties
file and the<
INSTALL
>/javaeetutorial5/examples/common/admin-password.txt
file. See Building the Examples (page xxxi) for information on which properties need to be set in which files.- If you have not already done so, add a user to the
file
realm and specifyuser
for the group of this new user. Refer to the section Managing Users and Groups on the Application Server (page 879) for instructions on completing this step.- From a terminal window or command prompt, go to the
<
INSTALL
>/javaeetutorial5/examples/ejb/cart-secure/
directory.- Build, package, and deploy the enterprise application, and build and run the client, by entering the following at the terminal window or command prompt in the
ejb/cart-secure/
directory:
ant all
Note: This step assumes that you have the executable for
ant
in your path; if not, you will need to provide the fully qualified path to theant
executable. This command runs theant
target namedall
in thebuild.xml
file.
A
Login for User
dialog displays. Enter a user name and password that correspond to a user set up on the Application Server with a group ofuser
. Click OK.If the user name and password are authenticated, the client displays the following output:
run: [echo] Running appclient for Cart. appclient-command-common: [exec] Infinite Jest [exec] Bel Canto [exec] Kafka on the Shore [exec] Caught a BookException: "Gravity's Rainbow" not in cart. BUILD SUCCESSFULIf the username and password are not authenticated, the client displays the following error:
run: [echo] Running appclient for Cart. appclient-command-common: [exec] Caught an unexpected exception! [exec] javax.ejb.EJBException: nested exception is: java.rmi.AccessException: CORBA NO_PERMISSION 9998 Maybe; nested exception is: [exec] org.omg.CORBA.NO_PERMISSION
: ----------BEGIN server-side stack trace---------- [exec] org.omg.CORBA.NO_PERMISSION: vmcid: 0x2000 minor code: 1806If you see this response, verify the user name and password of the user that you entered in the login dialog, make sure that user is assigned to the group user, and re-run the client application.
Example: Using isCallerInRole and getCallerPrincipal
This example demonstrates how to use the
getCallerPrincipal()
andisCallerInRole(String role)
methods with an enterprise bean. This example starts with a very simple EJB application,converter
, and modifies the methods of theConverterBean
so that currency conversion will only occur when the requester is in the role ofBeanUser
.For this tutorial, we will add the security elements to an enterprise bean; build, package, and deploy the application; and then build and run the client application. The completed version of this example can be found at
<
INSTALL
>/javaeetutorial5/examples/ejb/converter-secure
. This example was developed by starting with the unsecured enterprise bean application,converter
, which is found in the directory<
INSTALL
>/javaeetutorial5/examples/ejb/converter
and is discussed in Chapter 21, "Getting Started with Enterprise Beans". This section builds on this example by adding the necessary elements to secure the application using thegetCallerPrincipal()
andisCallerInRole(String role)
methods, which are discussed in more detail in Accessing an Enterprise Bean Caller's Security Context.In general, the following steps are necessary when using the
getCallerPrincipal()
andisCallerInRole(String role)
methods with an enterprise bean. In the example application included with this tutorial, many of these steps have been completed for you and are listed here simply to show what needs to be done should you wish to create a similar application.
- Create a simple enterprise bean application, such as the
converter
example that is described in Chapter 21, "Getting Started with Enterprise Beans". This section of the tutorial starts with this unsecured application and demonstrates how to access an enterprise bean caller's security context. The completed example application discussed in this section can be found at<
INSTALL
>/javaeetutorial5/examples/ejb/converter-secure/
.- If you have not already done so, specify properties specific to your installation in the
<
INSTALL
>/javaeetutorial5/examples/bp-project/build.properties
file and the<
INSTALL
>/javaeetutorial5/examples/common/admin-password.txt
file. See Building the Examples (page xxxi) for information on which properties need to be set in which files.- If you have not already done so, set up a user on the Application Server in the
file
realm. Make sure that the user is included in the group nameduser
. For information on adding a user to thefile
realm, read Managing Users and Groups on the Application Server (page 879).- Modify
ConverterBean
to add thegetCallerPrincipal()
andisCallerInRole(String role)
methods. For this example, callers that are in the role ofBeanUser
will be able to calculate the currency conversion. Callers not in the role ofBeanUser
will see a value of zero for the conversion amount. Modifying theConverterBean
code is discussed in Modifying ConverterBean.- Modify the
sun-ejb-jar.xml
file to specify a secure connection, username-password login, and security role mapping. Modifying thesun-ejb-jar.xml
file is discussed in Modifying Runtime Properties for the Secure Converter Example.- Build, package, deploy, and run the application. These steps are discussed in Building, Packaging, Deploying, and Running the Secure Converter Application.
- If necessary, refer to the tips in Troubleshooting the Secure Converter Application for tips on errors you might encounter and some possible solutions.
Modifying ConverterBean
The source code for the original
/converter
application was modified as shown in the following code snippet (modifications inbold
) to add theif..else
clause that tests if the caller is in the role ofBeanUser
, and, if the user is in the correct role, the method does the currency conversion. If the user is not in the correct role, the result is0
. The following code example can be found in<
INSTALL
>/javaeetutorial5/examples/ejb/converter-secure/converter-secure-ejb/src/java/converter/secure/ejb/ConverterBean.java
.package converter.secure.ejb; import java.math.BigDecimal; import javax.ejb.*;import java.security.Principal; import javax.annotation.Resource; import javax.ejb.SessionContext; import javax.annotation.security.DeclareRoles; import javax.annotation.security.RolesAllowed;
@Stateless()@DeclareRoles("BeanUser")
public class ConverterBean implements converter.secure.ejb.Converter {@Resource SessionContext ctx;
private BigDecimal yenRate = new BigDecimal("115.3100"); private BigDecimal euroRate = new BigDecimal("0.0071");@RolesAllowed("BeanUser")
public BigDecimal dollarToYen(BigDecimal dollars) {BigDecimal result = new BigDecimal("0.0");
Principal callerPrincipal = ctx.getCallerPrincipal();
if (ctx.isCallerInRole("BeanUser")) {
result = dollars.multiply(yenRate); return result.setScale(2, BigDecimal.ROUND_UP);}else{
return result.setScale(2, BigDecimal.ROUND_UP); } }@RolesAllowed("BeanUser")
public BigDecimal yenToEuro(BigDecimal yen) {BigDecimal result = new BigDecimal("0.0"); Principal callerPrincipal = ctx.getCallerPrincipal();
if (ctx.isCallerInRole("BeanUser")) {
result = yen.multiply(euroRate); return result.setScale(2, BigDecimal.ROUND_UP);}else{
return result.setScale(2, BigDecimal.ROUND_UP); } } }Modifying Runtime Properties for the Secure Converter Example
Secure connections, username-password login, and the mapping of application roles to Application Server groups and principals are specified in the runtime deployment descriptor file
sun-ejb-jar.xml
. The originalconverter
application that did not include any security mechanisms did not have a need for this file: it has been added specifically for this application.To map the role of
BeanUser
that is defined for this application to the group with the name ofuser
in the file realm of the Application Server, specify thesecurity-role-mapping
element as shown below. Make sure that therole-name
andgroup-name
elements are specified exactly as they are used (the mapping is case-sensitive).To specify username-password login and a secure connection, use the
ior-security-config
element. The IOR security elements are described in more detail in Configuring IOR Security.The following
sun-ejb-jar.xml
file demonstrates how to specify a secure connection, username-password login, and security role mapping. The completed version of this file can be found in<
INSTALL
>/javaeetutorial5/examples/ejb/converter-secure/converter-secure-ejb/src/conf/sun-ejb-jar.xml
.<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE sun-ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Application Server 9.0 EJB 3.0//EN" "http://www.sun.com/software/appserver/dtds/sun-ejb-jar_3_0-0.dtd"> <sun-ejb-jar> <security-role-mapping> <role-name>BeanUser</role-name> <group-name>user</group-name> </security-role-mapping> <enterprise-beans> <unique-id>0</unique-id> <ejb> <ejb-name>ConverterBean</ejb-name> <jndi-name>ConverterBean</jndi-name> <pass-by-reference>false</pass-by-reference> <ior-security-config><transport-config> <integrity>supported</integrity> <confidentiality>supported</confidentiality>
<establish-trust-in-target>supported</establish-trust-in-target> <establish-trust-in-client>supported</establish-trust-in-client> </transport-config> <as-context><auth-method>username_password</auth-method>
<realm>file</realm> <required>true</required> </as-context> <sas-context> <caller-propagation>supported</caller-propagation> </sas-context> </ior-security-config> <is-read-only-bean>false</is-read-only-bean> <refresh-period-in-seconds>-1</refresh-period-in-seconds> <gen-classes/> </ejb> </enterprise-beans> </sun-ejb-jarBuilding, Packaging, Deploying, and Running the Secure Converter Application
To build the secure converter enterprise beans and client, package and deploy the enterprise application, and run the client application, follow these steps:
- Set up your system for running the tutorial examples if you haven't done so already by following the instructions in Building the Examples (page xxxi).
- From a terminal window or command prompt, go to the
<
INSTALL
>/javaeetutorial5/examples/ejb/converter-secure/
directory.- Build, package, deploy, and run the enterprise application and application client by entering the following at the terminal window or command prompt in the
ejb/converter-secure/
directory:
ant all
Note: This step assumes that you have the executable for
ant
in your path; if not, you will need to provide the fully qualified path to theant
executable. This command runs theant
target namedall
in thebuild.xml
file.
The running application will look like this:
appclient-command-common: At this point, a system login dialog will display. Enter the user name and pass- word that correspond to a user in the group user on the Application Server. If the user name and password are authenticated, the following text displays in the terminal window or command prompt: appclient-command-common: [exec] $100.00 is 11531.00 Yen. [exec] 11531.00 Yen is 81.88 Euro. BUILD SUCCESSFULTroubleshooting the Secure Converter Application
- Problem: The application displays zero values after authentication, as shown here:
appclient-command-common:
[exec] $100.00 is 0.00 Yen.
[exec] 0.00 Yen is 0.00 Euro.
BUILD SUCCESSFULSolution: Verify that the username and password that you entered for authentication match a user name and password in the Application Server, and that this user is assigned to the group named user. User names and passwords are case-sensitive. Read Adding Users to the Application Server (page 879) for more information on adding users to the
file
realm of the Application Server.Discussion: Securing the Duke's Bank Example
The Duke's Bank application is an online banking application. Duke's Bank has two clients: an application client used by administrators to manage customers and accounts, and a web client used by customers to access account histories and perform transactions. The clients access the customer, account, and transaction information maintained in a database through enterprise beans. The Duke's Bank application demonstrates the way that many of the component technologies presented in this tutorial--enterprise beans, application clients, and web components--are applied to provide a simple but functional application.
To secure the Duke's Bank example, the following security mechanisms are used:
For more information on securing the Duke's Bank example, read Chapter 38, "The Duke's Bank Application".