The following example applications demonstrate adding security to enterprise beans applications:
Example: Securing an Enterprise BeanIn this section, we discuss how to configure an enterprise bean for username-password authentication. When a bean that is constrained in this way is 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 1010). For this tutorial, we will add the security elements to an enterprise bean; add security elements to the deployment descriptors; 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 771). 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.
Annotating the BeanThe source code for the original cart application was modified as shown in the following code snippet (modifications in bold, method details removed to save space). 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 of CartUser 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 PropertiesThe role of CartUser has been defined for this application, but there is no group of CartUser 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 on this topic, read Specifying an Authentication Mechanism (page 947) and Configuring IOR Security (page 959). Building, Deploying, and Running the Secure Cart Example Using NetBeans 5.5Follow these instructions to build, deploy, and run the cart-secure example in your Application Server instance using NetBeans 5.5.
If the username and password you enter are authorized, you will see the output of the application client in the Output pane: ... Retrieving book title from cart: Infinite Jest Retrieving book title from cart: Bel Canto Retrieving book title from cart: Kafka on the Shore Removing "Gravity's Rainbow" from cart. Caught a BookException: "Gravity's Rainbow" not in cart. Java Result: 1 run-cart-app-client: run-nb: Building, Deploying, and Running the Secure Cart Example Using AntTo build, deploy, and run the secure EJB example using the Ant tool, follow these steps:
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 the ant executable. This command runs the ant target named all in the build.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 of user. 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. If 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: 1806 If 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 rerun the client application. Example: Using the isCallerInRole and getCallerPrincipal MethodsThis example demonstrates how to use the getCallerPrincipal() and isCallerInRole(String role) methods with an enterprise bean. This example starts with a very simple EJB application, converter, and modifies the methods of the ConverterBean so that currency conversion will only occur when the requester is in the role of BeanUser. For this tutorial, we will add the security elements to an enterprise bean; add the security elements to the deployment descriptor; 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 discussed in Chapter 21 and is found in the directory <INSTALL>/javaeetutorial5/examples/ejb/converter/. This section builds on this example by adding the necessary elements to secure the application using the getCallerPrincipal() and isCallerInRole(String role) methods, which are discussed in more detail in Accessing an Enterprise Bean Caller's Security Context (page 940). In general, the following steps are necessary when using the getCallerPrincipal() and isCallerInRole(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.
Modifying ConverterBeanThe source code for the original /converter application was modified as shown in the following code snippet (modifications in bold) to add the if..else clause that tests if the caller is in the role of BeanUser. If the user is in the correct role, the currency conversion is computed and displayed. If the user is not in the correct role, the computation is not performed, and the application displays the result as 0. 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 ExampleSecure 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 original converter 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 of user in the file realm of the Application Server, specify the security-role-mapping element as shown below. Make sure that the role-name and group-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 (page 959). 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-jar Building, Deploying, and Running the Secure Converter Example Using NetBeans 5.5Follow these instructions to build, package, and deploy the converter-secure example to your Application Server instance using NetBeans 5.5.
Building, Deploying, and Running the Secure Converter Example Using AntTo build the secure converter enterprise beans and client, package and deploy the enterprise application, and run the client application, follow these steps:
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 the ant executable. This command runs the ant target named all in the build.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 password 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. Troubleshooting the Secure Converter ApplicationProblem: 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. Solution: Verify that the user name 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 918) for more information on adding users to the file realm of the Application Server. Discussion: Securing the Duke's Bank ExampleThe 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 tutorialenterprise beans, application clients, and web componentsare applied to provide a simple but functional application. To secure the Duke's Bank example, the following security mechanisms are used:
Read Chapter 37 for more information on securing the Duke's Bank example. |