Securing Enterprise Java Beans (EJBs) is one of the most important aspects of Java EE application security. IBM WebSphere Application Server Community Edition V2.1 (hereafter referred to as Community Edition) is a free-to-use Java Enterprise Edition 5.0 (Java EE5) certified application server based on Apache Geronimo v2.1 that provides for securing EJB applications. Community Edition uses Apache OpenEJB as its EJB container. You configure EJB authentication and authorization by defining security roles in the deployment descriptor under which each method executes. You then map the security roles to principals in the Community Edition specific deployment plan.
In this article we discuss the different options available to secure session, entity and message-driven EJBs using Community Edition. We also develop a few EJB applications to demonstrate the various security configurations. To follow along you need WebSphere Application Server Community Edition v2.1.
A simple EJB application without security
Let's examine a simple EJB application that has no security configured. This application contains an EJB2.1 stateless session bean and an EJB3 stateless session bean. Listing 1 shows this application's deployment descriptor ejb-jar.xml.
Listing 1: Deployment descriptor showing bean definition
<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar ...>
<display-name>SimpleEjbApp</display-name>
<enterprise-beans>
<session>
<description>Simple Session Bean</description>
<display-name>SimpleSessionBean</display-name>
<ejb-name>SimpleSessionBean</ejb-name>
<home>simple.ejb21.SimpleServiceHome</home>
<remote>simple.ejb21.SimpleService</remote>
<local-home>simple.ejb21.SimpleServiceLocalHome</local-home>
<local>simple.ejb21.SimpleServiceLocal</local>
<ejb-class>simple.ejb21.SimpleServiceBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
</session>
</enterprise-beans>
</ejb-jar>
|
Notice that the deployment descriptor shows only one bean definition, namely SimpleSessionBean. We specify the deployment metadata of the EJB3 session bean using annotations in the bean class. Listing 2 shows the bean class of Simple3ServiceBean.
Listing 2: Simple3ServiceBean class
import javax.ejb.Stateless;
...
@Stateless
public class Simple3ServiceBean implements Simple3Service {
public String commonMethod(){
...
}
public String userMethod(){
...
}
public String adminMethod(){
...
}
public String noaccessMethod(){
...
}
}
|
In this example the @Stateless annotation specifies that Simple3ServiceBean is a stateless session bean.
Both the session beans SimpleSessionBean and Simple3ServiceBean do not have any security configured and so all the methods have unrestricted access. The deployment plan openejb-jar.xml for this application is show in Listing 3.
Listing 3: Simple EJB application deployment plan
<openejb-jar ...>
<environment>
<moduleId>
<groupId>dw</groupId>
<artifactId>simple-ejb-app</artifactId>
<version>1.0</version>
<type>jar</type>
</moduleId>
<dependencies/>
<hidden-classes/>
<non-overridable-classes/>
</environment>
<enterprise-beans>
<session>
<ejb-name>SimpleSessionBean</ejb-name>
<jndi-name>ejb/SimpleSessionBean</jndi-name>
</session>
</enterprise-beans>
</openejb-jar>
|
The EJB application is deployed under a module with ID dw/simple-ejb-app/1.0/jar. Note that we'll use the information under moduleId element to map to the EJBs in this application as we will see later in this article.
A simple web application to demonstrate EJB security
In this article, we use a simple Web application to demonstrate EJB security. The Web application uses two security roles namely “bank” and “customer”. The Web application consists of a home page with unrestricted access and two secure pages accessible by “bank” and “customer” roles. Each of the pages access SimpleSessionBean and Simple3ServiceBean methods and display the result from the method or any exceptions thrown at method invocation. Listing 4 shows the web.xml deployment descriptor.
Listing 4: Simple web application deployment-descriptor
<web-app ...>
<display-name>simple-web-app</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
...
</welcome-file-list>
<login-config>
<auth-method>FORM</auth-method>
<realm-name>Not required for FORM auth</realm-name>
<form-login-config>
<form-login-page>/login/login.jsp</form-login-page>
<form-error-page>/login/loginerror.jsp</form-error-page>
</form-login-config>
</login-config>
<security-role>
<role-name>customer</role-name>
</security-role>
<security-role>
<role-name>bank</role-name>
</security-role>
<security-constraint>
<web-resource-collection>
<web-resource-name>Customer</web-resource-name>
<url-pattern>/customer/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>customer</role-name>
<!-- This comes from the security-role element -->
</auth-constraint>
</security-constraint>
<security-constraint>
<web-resource-collection>
<web-resource-name>Bank</web-resource-name>
<url-pattern>/bank/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>bank</role-name>
<!-- This comes from the security-role element -->
</auth-constraint>
</security-constraint>
<ejb-ref>
<ejb-ref-name>ejb/SimpleService</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<home>simple.ejb21.SimpleServiceHome</home>
<remote>simple.ejb21.SimpleService</remote>
</ejb-ref>
<ejb-ref>
<ejb-ref-name>ejb/Simple3Service</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<remote>simple.ejb3.Simple3Service</remote>
</ejb-ref>
....
</web-app>
|
The Web application uses FORM authentication as configured in the login-config element. The two security roles are defined using security-role elements. We use the security-constraint tag to configure security permissions for resource collections. In this sample, users in the bank role can access URLs with the pattern /bank/* and users in the customer role can access URLs with pattern /customer/*.
We use the ejb-ref element to declare EJB references for accessing the bean through its remote home and remote interfaces. In this sample, we define two EJB references namely ejb/SimpleService and ejb/Simple3Service. Notice that there is no home interface defined for the Simple3Service bean, which is an EJB3 session bean. You can use the ejb-local-ref element to declare EJB references used for accessing the bean through its local home and local interfaces.
In the geronimo-web.xml Web application deployment plan, we
map the EJB references defined in web.xml to specific EJBs, and map the security roles to principals. Listing 5 shows the deployment plan for the sample Web application.
Listing 5: Simple web application deployment plan
<web-app ...>
...
<context-root>simple-web-app</context-root>
<nam:ejb-ref xmlns:nam="http://geronimo.apache.org/xml/ns/naming-1.2">
<nam:ref-name>ejb/SimpleService</nam:ref-name>
<nam:pattern>
<nam:groupId>dw</nam:groupId>
<nam:artifactId>simple-ejb-app</nam:artifactId>
<nam:version>1.0</nam:version>
<nam:name>SimpleSessionBean</nam:name>
</nam:pattern>
</nam:ejb-ref>
<nam:ejb-ref xmlns:nam="http://geronimo.apache.org/xml/ns/naming-1.2">
<nam:ref-name>ejb/Simple3Service</nam:ref-name>
<nam:pattern>
<nam:groupId>dw</nam:groupId>
<nam:artifactId>simple-ejb-app</nam:artifactId>
<nam:version>1.0</nam:version>
<nam:name>Simple3ServiceBean</nam:name>
</nam:pattern>
</nam:ejb-ref>
...
<security-realm-name>SampleSecurityRealm</security-realm-name>
<app:security ...>
...
<sec:role-mappings>
<sec:role role-name="customer">
<sec:principal name="UserGrp"
class="o.a.g.s.r.providers.GeronimoGroupPrincipal"/>
...
</sec:role>
<sec:role role-name="bank">
<sec:principal name="AdminGrp"
class="o.a.g.s.r.providers.GeronimoGroupPrincipal"/>
...
</sec:role>
</sec:role-mappings>
</app:security>
</web-app>
|
We use the ejb-ref element to map
an EJB reference to specific EJBs. In this example, notice that the value in the
ref-name element under ejb-ref matches the value in ejb-ref-name element under ejb-ref in
web.xml (see Listing 4). Similarly, we use the ejb-local-ref element to map EJB local references to specific EJBs.
The security-realm-name element is used to configure the security realm against which the application authenticates the users. In this example, we use a realm with name SampleSecurityRealm.
The security roles are mapped to principals under the role-mappings element inside the security
element. We use a role element for each security role to
be mapped. The name of the security role is specified in the role-name attribute of the role element.
We specifiy the principals that map to the security role using principal elements
inside the role element. In this example, we map the bank
role to a GeronimoGroupPrincipal with name AdminGrp and the customer role to a GeronimoGroupPrincipal with
name UserGrp. See Configuring Web application
security in WebSphere Application Server Community Edition V2.0 provided in the
Resources for a detailed explanation of principal to role mapping.
Run the sample application without EJB security
We will now run the simple Web application that accesses the EJBs in the EJB application. Note that at the moment we have no security configured for the EJBs. Before proceeding further, download and extract the samples archive to a directory of your choice, (we will refer to this directory as <SAMPLES_HOME>) and copy dw_users.properties and dw_groups.properties files to <WASCE_HOME>/var/security directory (<WASCE_HOME> refers to the Community Edition installation directory).
To run the sample application:
-
Start Community Edition and open
http://localhost:8080/console/in your browser. -
Enter
systemfor the user name andmanagerfor the password. Click Login, which brings up the Welcome page in the administrative console. - Navigate to the Deploy New portlet.
-
Under the Plan field, navigate to
<SAMPLES_HOME>and select the fileSampleSecurityRealm-plan.xml. - Click Install to complete the security realm deployment.
-
Under the Archive field, navigate to
<SAMPLES_HOME>and select simple-ejb-app.jar. - Click Install to complete EJB application deployment.
-
Under the Archive field, navigate to
<SAMPLES_HOME>and select simple-web-app.war. - Click Install to complete Web application deployment.
-
Access
http://localhost:8080/simple-web-app, which shows the screen in Figure 1.
Figure 1: Web application home page
The User Info section shows the currently logged in user's
UserPrincipalandUserRolesin the web application. The EJB2.1 section shows the result of invoking each of the methods inSimpleSessionBean. The EJB3 section shows the result of invoking each of the methods inSimple3ServiceBean. Since we have not logged into the application, theUserPrincipalandUserRoleis empty. Since no security is configured for any of the EJB methods, all the methods are accessible and are invoked as an Unauthenticated user. -
Access
http://localhost:8080/simple-web-app/bank. Login as userdwadminusing passwordadmin,which shows the screen in Figure 2.
Figure 2: Web application bank page
Notice that the
UserPrincipalshows the logged in userdwadminand the UserRole asbank. Since no security is configured for any of the EJB methods, all the methods are accessible and are invoked as an Unauthenticated user.
So far we have seen the Web application invoking EJB2.1 and EJB3 session beans with unrestricted method access. Next we'll configure method permissions for EJB2.1 and EJB3 session beans.
Security configuration in EJB2.1 deployment descriptors
EJB applications use role-based security for bean-level and method-level security. In this section we see how to define security roles and configure method permissions.
We define security roles in the deployment descriptor file ejb-jar.xml using a security-role element under assembly-descriptor. The role-name element specifies the name of the security role. Listing 6 shows an excerpt of ejb-jar.xml from one of the sample applications used in this article.
Listing 6: Assembly-descriptor showing role definitions
<ejb-jar ...>
<display-name>SimpleEjbApp</display-name>
<enterprise-beans>
...
</enterprise-beans>
<assembly-descriptor>
<security-role>
<description>User role</description>
<role-name>ejbuser</role-name>
</security-role>
<security-role>
<description>Administrator role</description>
<role-name>ejbadmin</role-name>
</security-role>
...
</assembly-descriptor>
</ejb-jar>
|
In this example the application defines two roles, namely ejbuser and ejbadmin.
Configuring method permissions
To configure the security identity to invoke the methods in an EJB, we use the security-identity element in the bean definitions under enterprise-beans element in ejb-jar.xml. We configure the bean method permissions by using the method-permission element under assembly-descriptor in ejb-jar.xml. Listing 7 shows fragments of the EJB application deployment descriptor used to configure the method permissions for SimpleSessionBean.
Listing 7: EJB application deployment descriptor
<ejb-jar id="SimpleEjbAppWithSecurity" ...>
<enterprise-beans>
<session>
...
<ejb-name>SimpleSessionBean</ejb-name>
...
<security-identity>
<use-caller-identity />
</security-identity>
</session>
...
</enterprise-beans>
<assembly-descriptor>
<security-role>
...
</security-role>
<method-permission>
<role-name>ejbuser</role-name>
<method>
<ejb-name>SimpleSessionBean</ejb-name>
<method-name>userMethod</method-name>
</method>
</method-permission>
<method-permission>
<role-name>ejbadmin</role-name>
<method>
<ejb-name>SimpleSessionBean</ejb-name>
<method-name>adminMethod</method-name>
</method>
</method-permission>
<method-permission>
<unchecked/>
<method>
<ejb-name>SimpleSessionBean</ejb-name>
<method-name>commonMethod</method-name>
</method>
</method-permission>
<method-permission>
<role-name/>
<method>
<ejb-name>SimpleSessionBean</ejb-name>
<method-name>noaccessMethod</method-name>
</method>
</method-permission>
</assembly-descriptor>
</ejb-jar>
|
Let's walk through the tags we used in this example:
-
The
security-identityelement specifies the security identity to be used to invoke methods inSimpleSessionBean. -
The
use-caller-identityelement specifies that the caller's security identity be used as the security identity for the execution of the enterprise bean's methods. Another option is to use arun-aselement to specify that a run-as identity be used to invoke the bean's methods as we show later in this article.
-
The
method-permission'smethodelement specifies the security permissions for one or more methods in a bean. -
You can specify permissions using one or more
role-nameelements, one for each role that is allowed to access the method. A single, emptyrole-nameelement means the role has no access to the method. You specify unrestricted access permission using anuncheckedelement. -
The method's
ejb-nameelement specifies the name of the EJB. Themethod-nameelement specifies the name of the method. A value of“*”formethod-namecorresponds to all methods in the EJB. -
A specific
method-namecorresponds all methods of that name, including any overloaded methods. To specify a particular method from overloaded methods, use themethod-paramselement. -
You can configure
method-permissionfor methods in the bean's Home, Remote, Local and LocalHome interfaces. To specify the permission for a method in a particular interface, use themethod-intfelement under method with the corresponding value.
In Listing 7, in the SimpleSession bean, we have configured:
-
userMethodto be accessible byejbuserrole. -
adminMethodto be accessible byejbadminrole. -
commonMethodto have unrestricted access. -
noaccessMethodto be inaccessible by any role.
Security configuration in EJB3 beans using annotations
In EJB3 enterprise beans, you can configure the bean-level and method-level security using security annotations. In this section, we discuss the various security annotations (@DeclareRoles, @DenyAll, @PermitAll, @RolesAllowed) and how they affect the security configuration. Note that we'll discuss the @RunAs annotation later in the article.
You define security roles by using a @DeclareRoles annotation on a bean class, as shown in Listing 8.
Listing 8: Simple3ServiceBean with @DeclareRoles annotation
@Stateless
@DeclareRoles({"ejb3user", "ejb3admin"})
public class Simple3ServiceBean implements Simple3Service {
...
}
|
In this example, Simple3ServiceBean defines two security roles, namely ejb3user and ejb3admin.
Configuring method permissions
You configure permissions for enterprise beans methods using the @DenyAll, @PermitAll and @RolesAllowed annotations. The @PermitAll and @RolesAllowed annotations can be applied on the bean class as well as bean methods, whereas @DenyAll annotation can be applied only on bean methods. An annotation applied on a class is applicable to all the methods in the class. An annotation applied on a method overrides any annotation applied on the class. Listing 9 shows Simple3ServiceBean class.
Listing 9: Simple3ServiceBean class with security annotations
@Stateless
@DeclareRoles({"ejb3user", "ejb3admin"})
public class Simple3ServiceBean implements Simple3Service {
@Resource
private SessionContext ctx;
@PermitAll
public String commonMethod() {
return logCall("commonMethod");
}
@RolesAllowed({"ejb3user"})
public String userMethod() {
return logCall("userMethod");
}
@RolesAllowed({"ejb3admin"})
public String adminMethod() {
return logCall("adminMethod");
}
@DenyAll
public String noaccessMethod() {
return logCall("noaccessMethod");
}
private String logCall(String method) {
...
return msg;
}
}
|
This example defines the following access configuration:
-
commonMethodhas unrestricted access. -
userMethodis accessible by ejb3user role. -
adminMethodis accessible by ejb3admin role. -
noaccessMethodis not accessible by any role.
Security role mapping in the EJB deployment plan
The security roles defined in the EJB deployment descriptor and the roles defined using the @DeclareRoles annotation are mapped to principals in the EJB deployment plan openejb-jar.xml. shows the principal to role mapping in the EJB deployment plan.
Listing 10: principal to role mapping
<security>
<role-mappings>
<role role-name="ejbuser">
<principal class="o.a.g.s.r.providers.GeronimoGroupPrincipal"
name="UserGrp"/>
</role>
<role role-name="ejbadmin">
<principal class="o.a.g.s.r.providers.GeronimoGroupPrincipal"
name="AdminGrp"/>
</role>
<role role-name="ejb3user">
<principal class="o.a.g.s.r.providers.GeronimoGroupPrincipal"
name="UserGrp"/>
</role>
<role role-name="ejb3admin">
<principal class="o.a.g.s.r.providers.GeronimoGroupPrincipal"
name="AdminGrp"/>
<principal class="o.a.g.s.r.providers.GeronimoUserPrincipal"
name="dwuser3"/>
</role>
</role-mappings>
</security>
|
Notice that the security roles in ejb-jar.xml and in the @DeclareRoles annotation are mapped to principals:
-
The
ejbuserrole is mapped to aGeronimoGroupPrincipalwith name“UserGrp”. -
The
ejbadminrole us mapped to aGeronimoGroupPrincipalwith name“AdminGrp”. -
The
ejb3userrole is mapped to aGeronimoGroupPrincipal with name“UserGrp”. -
The
ejb3adminrole is mapped to aGeronimoGroupPrincipalwith name“AdminGrp”and aGeronimoUserPrincipalwith name“dwuser3”.
See Configuring Web application security in WebSphere Application Server Community Edition V2.0 for a detailed explanation of the principal to role mapping.
Run the sample application with EJB security
Navigate to the Deploy New portlet.
- Under the Archive files, navigate to <SAMPLES_HOME> and select simple-ejb-app-w-security.jar.
- Select the Redeploy application option and click Install.
- Navigate to the Web App WARs portlet and start dw/simple-web-app/1.0/war.
-
Access
http://localhost:8080/simple-web-app, which shows the screen in Figure 3.
Figure 3: Web application home page accessing secure EJBs
Note that since the user has not logged into the application, only
commonMethodinSimpleSessionBeanandSimple3ServiceBean(which has unrestricted access) is invokable from the home page. All the other method invocations resulted inAccessExceptionorEJBAccessExceptionsince thePrincipalis not authorized. - Access
http://localhost:8080/simple-web-app/bank/. Log in with namedwadminusing passwordadmin,which shows the screen in Figure 4.
Figure 4: Web application bank page accessing secure EJBs
Since the user is now logged in as
dwadmin, theSubjectcontainsGeronimoUserPrincipalwith namedwadminandGeronimoGroupPrincipalwith nameAdminGrp. The user maps toejbadminandejb3adminroles as per the role mapping. So the user can accesscommonMethod,which has unrestricted access, andadminMethod, which is accessible (by theejbadminrole forSimpleSessionBeanand theejb3adminrole forSimple3ServiceBean). TheuserMethodandnoaccessMethodresulted inAccessExceptionorEJBAccessExceptionupon invocation.userMethodis accessible by theejbuserrole (ejb3userrole forSimple3ServiceBean), andnoaccessMethodis not accessible by any role, - Open a new browser window and access
http://localhost:8080/simple-web-app/customer/. Login with namedwuser3using passworduser3,which shows the screen in Figure 5.
Figure 5: Web application customer page accessing secure EJBs
Since the user is now logged in as
dwuser3, theSubjectcontainsGeronimoUserPrincipalwith namedwuser3andGeronimoGroupPrincipalwith nameUserGrp. The user maps toejbuser,ejb3userandejb3admin roles as per the role mapping. InSimpleSessionBean, the user can accesscommonMethod,which has unrestricted access and theuserMethodthat is accessible by theejbuser role . In Simple3ServiceBean, the user can accesscommonMethod,which has unrestricted access, theuserMethodthat is accessible by theejb3userrole andadminMethod which is accessible byejb3adminrole (see Security configuration in EJB2.1 deployment descriptors). All the other methods resulted inAccessExceptionorEJBAccessExceptionupon invocation.
In addition to configuring method permissions for a bean's methods, you can configure a Run-as role for the bean to specify the security identity with which the bean invokes other beans. This configuration is useful when a bean's method needs to invoke other beans with a different security identity than the security identity with which it is invoked, e.g. a message-driven bean method, which is invoked with no security identity, invoking a secured session-bean method. You configure the security credentials that constitute the subject for run-as role security in the deployment plan.
In Community Edition releases prior to 2.0, security configuration for run-as and default subjects was constructed using the principals and credentials specified using default-principal tag and designated-run-as attribute of principal. Starting from Community Edition 2.0, all security flows from subjects resulting from logging into a security realm. To use these subjects, you need to supply login information for each such subject. This login information is captured in a credential store.
Community Edition provides an implementation of credential store, namely SimpleCredentialStoreImpl that enables configuring a credential store using XML in the deployment plans. Listing 11 shows the credential store we used in the sample applications in this article.
Listing 11: Credential Store gbean
<gbean name="SampleCredentialStore"
class="o.a.g.s.credentialstore.SimpleCredentialStoreImpl" ...>
<xml-attribute name="credentialStore">
<credential-store
xmlns="http://geronimo.apache.org/xml/ns/credentialstore-1.0">
<realm name="SampleSecurityRealm">
<subject>
<id>dwuser1-subject</id>
<credential>
<type>o.a.g.s.credentialstore.NameCallbackHandler</type>
<value>dwuser1</value>
</credential>
<credential>
<type>o.a.g.s.credentialstore.PasswordCallbackHandler</type>
<value>user1</value>
</credential>
</subject>
<subject>
<id>dwuser2-subject</id>
...
</subject>
<subject>
<id>dwuser3-subject</id>
...
</subject>
<subject>
<id>dwadmin-subject</id>
...
</subject>
</realm>
<realm name="AnotherRealm">
<subject>
...
</subject>
...
</realm>
</credential-store>
</xml-attribute>
</gbean>
|
Here, the name attribute of the realm element specifies the name of the security-realm that you use to create the subject. The id element under the subject element specifies an ID for the subject, which can be used in combination with the security-realm name when configuring run-as and default subjects as we show later.
You use the credential element under the subject to configure the log-in information for the security-realm. In Listing 11,we obtain dwuser1-subject logging into SampleSecurityRealm using user name dwuser1 with password user1. Currently Community Edition provides callback handlers for name and password that are sufficient for using security realms that need name and password to authenticate. For using other security realms with the credential store, for example ones that use digital certificates, you need to implement the required callback handlers. Also, the credential stores can be per application, or you can have one credential store that is used by all applications.
Configuring application to use a credential store
You specify the credential store to be used by an application in the security configuration in the application's deployment plan. Listing 12 shows the security configuration of one of the sample applications used in this article.
Listing 12: Security configuration showing credential-store-ref
<security>
<credential-store-ref>
<name xmlns="http://geronimo.apache.org/xml/ns/deployment-1.2">
SampleCredentialStore</name>
</credential-store-ref>
...
</security>
|
In this example the name element under credential-store-ref specifies the credential store to be used by the application. Note that this value matches the name attribute of the credential store gbean shown in Listing 11.
Configuring run-as and default subjects
You specify the run-as and default subjects for the application in the security configuration in the application's deployment plan. If a run-as subject is not configured for any role, the configured default-subject will be used instead. Listing 13 shows the run-as and default subject configuration of one of the sample applications used in this article.
Listing 13: Security configuration showing run-as and default subjects
<security>
...
<default-subject>
<realm>SampleSecurityRealm</realm>
<id>dwuser1-subject</id>
</default-subject>
<role-mappings>
<role role-name="ejb3user">
<run-as-subject>
<realm>SampleSecurityRealm</realm>
<id>dwuser3-subject </id>
</run-as-subject>
<principal class="o.a.g.s.r.providers.GeronimoGroupPrincipal" name="UserGrp"/>
</role>
<role role-name="another">
...
</role>
...
</role-mappings>
</security>
|
The default-subject element under
the security element configures the default subject used by
the application. The realm element under default-subject specifies the security-realm, and the id element specifies the ID of the subject as configured in the credential store. Notice that value specified for the realm under default-subject matches the name attribute of the realm element in Listing 11. Also, note that the value specified for the id under default-subject matches one of the subject's id in Listing 11.
The run-as-subject element in the role element under role-mappings configures the run-as subject for that role. Listing 13 shows run-as subject configured for the ejb3user role. Notice that value specified for realm under run-as-subject matches the name attribute of the realm element in Listing 11. Also, note that the value specified for id under run-as-subject matches one of the subject's id in Listing 11.
Sample EJB application with run-as
We have added two more session beans (Simple3ServiceBean2 and Simple3SeviceBean3) that in turn invoke the corresponding methods in Simple3ServiceBean. We configured Simple3ServiceBean2 to run as ejb3user role. Simple3ServiceBean3 is not configured with a run-as role. Listing 14 shows the Simple3ServiceBean2 bean class.
Listing 14: Simple3ServiceBean2 class
@Stateless
@DeclareRoles(value = {"ejb3user", "ejb3admin"})
@RunAs("ejb3user")
public class Simple3ServiceBean2 implements Simple3Service2 {
@EJB
private Simple3Service simple; // Simple3Service injected here
@PermitAll
public String commonMethod() {
Object temp;
try {
temp = simple.commonMethod();
} catch(Throwable t) {
temp = t;
}
return logCall("commonMethod") + "::" + temp;
}
@RolesAllowed({"ejb3user"})
public String userMethod() {
...
}
@RolesAllowed({"ejb3admin"})
public String adminMethod() {
...
}
@DenyAll
public String noaccessMethod() {
...
}
private String logCall(String method) {
...
}
}
|
In this example, we used the @RunAs annotation with the ejb3user role to configure the run-as role for Simple3ServiceBean2. With this configuration, the invocation of methods on Simple3Service use the run-as-subject as specified in the deployment plan. Note that the run-as-subject for the ejb3user role is specified as dwuser3-subject (see Listing 13).
Run the sample application with run-as EJB security
- Navigate to the Deploy New portlet.
- Deploy simple-ejb-app-w-runas.jar provided in the samples. Make sure to select the Redeploy application option before clicking Install.
- Navigate to the Web App WARs portlet and start dw/simple-web-app/1.0/war.
- Access
http://localhost:8080/simple-web-app. Scroll down to the RunAs section which shows the screen in Figure 6.
Figure 6: Web application home page accessing EJBs with run-as
Notice under the RunAs section that the
commonMethodinSimple3ServiceBean2is invoked as an Unauthenticated user, but, in turn thecommonMethodinSimple3ServiceBeanis invoked asdwuser3as configured by run-as-subject. SinceSimple3ServiceBean3is not configured with run-as role, thecommonMethodinSimple3ServiceBeanis invoked as an Unauthenticated user. - Access
http://localhost:8080/simple-web-app/customer/. Login with namedwuser1using passworduser1. Scroll down to the RunAs section, which shows the screen in Figure 7.
Figure 7: Web application customer page accessing EJBs with run-as
Notice that under the RunAs section the commonMethod and userMethod in Simple3ServiceBean2 are invoked as dwuser1, the current user logged into the Web application. However, in turn the commonMethod and userMethod in Simple3ServiceBean are invoked as dwuser3 as configured by run-as-subject. Since Simple3ServiceBean3 is not configured with run as role, the commonMethod and userMethod in Simple3ServiceBean are invoked as dwuser1.
Configuring entity bean security
You can configure entity bean security using the deployment-descriptor and security annotations the same way as we did for session bean security. Listing 15 shows the assembly-descriptor from a sample EJB application with an entity bean.
Listing 15: Assembly-descriptor
<assembly-descriptor>
<security-role>
<description>Bank Manager</description>
<role-name>manager</role-name>
</security-role>
<method-permission>
<role-name>manager</role-name>
<method>
<ejb-name>MyBank</ejb-name>
<method-name>create</method-name>
</method>
</method-permission>
</assembly-descriptor>
|
In this example, we configured the create method on the Home interface of MyBank entity bean to be accessible only by the manager role.
Run the Entity bean sample application
The MyBankEJB sample application provided in the samples contains a single EJB2.1 entity bean named MyBank. We configured the create method in the bean's LocalHome and Home interfaces to be accessible only by the manager role.
Follow these steps to run the application:
- Navigate to the Deploy New portlet.
-
In the Archive field, browse to
<SAMPLES_HOME>and select bank-db-pool.rar. -
Click Install to deploy the database pool used by the
MyBankEJBapplication. -
In the Archive field, browse to
<SAMPLES_HOME>and select MyBankEJB.jar. -
Click Install to deploy the
MyBankEJBapplication. -
In the Archive field, browse to <
SAMPLES_HOME> and select MyBankWeb.war. -
Click Install to deploy the
MyBankWebapplication. -
Access
http://localhost:8080/MyBankWeb.Notice that the displayed page shows that an exception occurred in the Create an account section, because the user has not logged in.
-
Now access
http://localhost:8080/MyBankWeb/manager
Notice that the displayed page now shows that account creation is successful. It succeeded because the page is configured, using run-as role, to access the MyBank bean with the user ID dwadmin which maps to the manager role as configured in the MyBankEJB deployment plan.
Configuring Message-driven bean security
Unlike session and entity beans, message-driven beans are not invoked by other beans or client applications. They are invoked by a JMS listener when a message arrives on the input destination the listener is monitoring. Message-driven beans can invoke other session and entity beans. To invoke secure EJBs from a message-driven bean, the message-driven bean needs to be configured with a run-as role. For EJB2.1 message-driven bean, you can configure run-as role using the security-identity element in the deployment descriptor. For EJB3 message-driven bean, you configure run-as role cusing an @RunAs annotation.
Run the Message-driven bean sample application
To demonstrate the run-as security for an EJB3 message-driven bean, we have provided an application (jms-mdb-sample-ear-2.1.0.1.ear) in the sample. The application consists of one message-driven bean called OrderRecvMDB and a stateless session bean called Simple30ServiceBean. We configured the session bean's userMethod to be accessible by the ejb3user role, and the OrderRecvMDB bean with run-as role ejb3user. In the deployment plan, the security configuration specifies a run-as-subject dwuser1-subject for the ejb3user role. Listing 16 shows the OrderRecvMDB bean class:
Listing 16: OrderRecvMDB bean class
import javax.annotation.security.RunAs;
...
//
// MessageDrivenBean that listens to items on the
// 'OrderQueue' queue and processes them accordingly.
//
@MessageDriven(activationConfig = {
@ActivationConfigProperty(propertyName="destinationType",
propertyValue="javax.jms.Queue"),
@ActivationConfigProperty(propertyName="destination",
propertyValue="OrderQueue")
})
@RunAs("ejb3user")
public class OrderRecvMDB implements MessageListener {
@EJB
private Simple30Service simple; // Session bean is injected
/*
* Process a message.
*
* @param message The message to process.
*/
public void onMessage(Message message) {
TextMessage textMessage = (TextMessage) message;
try {
System.out.println("Order Received \n"+ textMessage.getText());
simple.userMethod();
} catch ( JMSException e ) {
e.printStackTrace();
}
}
}
|
Follow these steps to run the application:
- Navigate to the Deploy New portlet.
-
In the Archive field, browse to <
SAMPLES_HOME> and select jms-mdb-sample-ear-2.1.0.1.ear. - Click Install to deploy the sample application.
-
Access
http://localhost:8080/order. - Enter the field values and click Order.
Notice that the server console window displays the order received along with the details on the security identity dwuser1 with which the userMethod in Simple30ServiceBean is invoked.
We have created EJB2.1 and EJB3 session beans, an EJB2.1 entity bean, and configured access permissions for the bean methods using deployment descriptors and security annotations. We have also configured a run-as role for session and message-driven beans, and created the necessary artifacts like a credential store to deploy the EJB applications that use this security configuration. We have also demonstrated EJB security using sample Web applications to invoke the EJBs.
Thanks to Phani Madgula for reviewing this material.
| Description | Name | Size | Download method |
|---|---|---|---|
| Sample source code | samples.zip | 1.6MB | HTTP |
Information about download methods
Learn
-
WebSphere Application Server Community Edition product documentation
- WebSphere Application Server Community Edition
resources
-
Configuring Web application security in WebSphere Application Server Community Edition
V2.0
-
Apache Geronimo
-
Apache OpenEJB
- What’s new in WebSphere Application Server Community Edition V2.1
- Developing
JPA Applications with WebSphere Application Server Community Edition
- Developing Rich Internet Applications for WebSphere Application Server Community Edition
- WebSphere Application Server Community Edition support site
- WebSphere Application Server Community Edition documentation
- Develop applications on all the Java EE5 APIs
-
Get to know Java EE 5
-
WebSphere Application Server Community Edition Technical Support offerings
-
WebSphere Application Server Community Edition resources
- developerWorks Open Source zone
- developerWorks Web development zone
Get products and technologies
Discuss
- developerWorks WebSphere Application Server Community Edition and Apache Geronimo forum
- developerWorks Open Source forum

Vamsavardhana Reddy Chillakuru , a.k.a Vamsi, is an Advisory Software Engineer at IBM India Software Labs in Bangalore, India. He is a committer on Apache Geronimo and Apache Tuscany projects, a member of the Apache Geronimo Project Management Committee, and is part of the IBM WebSphere Application Server Community Edition Level 3 Support Team. He received his Bachelor of Statistics (Hons.) and Master of Statistics degrees from Indian Statistical Institute, Kolkata, India in the years 1994 and 1996 respectively.

Manu T. George is a Staff Software Engineer at IBM India Software Labs in Bangalore, India. He is a committer on Apache Geronimo and Apache OpenEJB projects, and is a part of the IBM WebSphere Application Server Community Edition Level 3 Support Team. He received his Bachelor of Technology in Applied Electronics from the College of Engineering Trivandrum in the year 2001.
Comments (Undergoing maintenance)





