A key aspect of the Java 2 Platform, Enterprise Edition (J2EE) component models is a simple declarative security model. The Enterprise JavaBean (EJB) 2.0 and Servlet 2.2 specifications support a role-based declarative security model that externalizes security from application logic and decouples the application security roles from the deployment environment's security implementation. At the application level, the
deployment descriptors define security. Although this model allows for an independent, simple specification of the application server's security requirements, mapping the application-defined security onto the deployment environment security's infrastructure is an application-server-specific activity. Thus, configuring a J2EE application's security requires proprietary application server APIs or tools. One such tool is the Java Authentication and Authorization Service (JAAS). In this article, I describe how the JBoss security extension, JBossSX, uses the standard JAAS to integrate with the deployment environment's security infrastructure. By configuring the JAAS login modules bundled with JBoss, you can complete the integration without custom programming. If the bundled login modules don't work with your security infrastructure, you can simply write a custom login module that does; I'll show you how in this article. The key topics that I cover here include:
- The J2EE declarative security model
- The key JAAS classes
- Details of how the JBossSX security manager uses JAAS in its implementation of the J2EE declarative security model
- Details of how you can write a custom JAAS login module for JBoss
I also include a secure enterprise application example that demonstrates the declarative security model and the configuration of JAAS login modules to integrate the deployment environment's security.
J2EE declarative security overview
The first step to securing a J2EE application is to specify the application security requirements via the standard J2EE deployment descriptors. You secure access to EJBs and Web components in an enterprise application by using the
deployment descriptors. Figures 1 and 2 illustrate the security-related elements in the EJB 2.0 and Servlet 2.2 deployment descriptors, respectively.
Together, these security elements define the bean author and application assembler's view of an enterprise application's security requirements.
So that you'll have sufficient background for the example presented later in this article, I'll first review the security elements pictured in Figures 1 and 2.
Enterprise beans security references
As you can see in Figure 1, enterprise beans may declare one or more
elements. An EJB can access the caller principal and ask if the caller belongs to a role by name. The caller principal is obtained from the
method as a
instance. Using the
method, an EJB checks if a caller is in a role that has been declared with a
element value must link to a security role in the assembly-descriptor section of
element. You typically use
to perform a security check that cannot be defined using method permissions. See section 21.2.5 of the
for more details on accessing the caller's security context.
Enterprise beans security identity
Figure 1 also shows that enterprise beans can optionally declare a
element. New to EJB 2.0 is the ability to specify what identity an EJB should use when it invokes methods on other EJBs. The application assembler uses the
element to indicate that the current caller's identity should be propagated by using a
's value. Alternatively, the application assembler can use the
element with the
's value as
to specify that EJB calls are performed with the security role given by the
value. Note that this does not change the caller's identity as seen by
. Rather, the caller's security roles are set to the single role specified by the
element value. You can use a
identity to keep external clients from accessing internal EJBs. To do that, assign the internal EJB method permissions that restrict access to a role never assigned to an external client, and use the restricted role as the
element value for EJBs that use the internal EJB.
Assembly descriptor security roles
The security role referenced by either
elements needs to map to one of the application's declared roles. An application assembler defines logical security roles by adding
elements to the
element. In JBoss, a
is only used to map an EJB
to the logical role to which the EJB role name refers. The user's assigned roles are a dynamic function of the application's security manager, as you will see when I discuss the JBossSX implementation. JBoss does not require defined
s to identify method permissions. Therefore, you should specify a
element for every role used in the
element for portability across application servers and for deployment descriptor maintenance.
Assembly descriptor method permissions
An application assembler can set the roles that are allowed to invoke an EJB's home and component interface methods through
element contains one or more
elements that define the logical roles allowed access to one or more EJB methods as identified by
elements. With EJB 2.0, you can now specify the
element instead of the
element to declare that an authenticated user can access one or more methods. In addition, you can declare that no one should have access to a method with the
element. For method syntax, see section 21.3.2 of the
An example EJB deployment descriptor
descriptor illustrates the use of EJB security elements and is the descriptor used in the article example:
<ejb-jar> <display-name>SecurityTests</display-name> <enterprise-beans> <session> <description>A trivial stateless session echo bean</description> <ejb-name>PublicSession</ejb-name> <home>org.jboss.docs.jaas.howto.SessionHome</home> <remote>org.jboss.docs.jaas.howto.Session</remote> <ejb-class>org.jboss.docs.jaas.howto.StatelessSessionBean</ejb-class> <session-type>Stateless</session-type> <transaction-type>Container</transaction-type> <ejb-ref> <ejb-ref-name>ejb/PrivateSession</ejb-ref-name> <ejb-ref-type>Session</ejb-ref-type> <home>org.jboss.docs.jaas.howto.SessionHome</home> <remote>org.jboss.docs.jaas.howto.Session</remote> <ejb-link>PrivateSession</ejb-link> </ejb-ref> <security-identity> <run-as> <role-name>InternalUser</role-name> </run-as> </security-identity> </session> <session> <description>A trivial stateful session echo bean</description> <ejb-name>PrivateSession</ejb-name> <home>org.jboss.docs.jaas.howto.SessionHome</home> <remote>org.jboss.docs.jaas.howto.Session</remote> <ejb-class>org.jboss.docs.jaas.howto.StatefulSessionBean</ejb-class> <session-type>Stateful</session-type> <transaction-type>Container</transaction-type> </session> </enterprise-beans> <assembly-descriptor> <security-role> <role-name>Coder</role-name> </security-role> <security-role> <role-name>Echo</role-name> </security-role> <security-role> <role-name>InternalUser</role-name> </security-role> <method-permission> <role-name>Echo</role-name> <method> <ejb-name>PublicSession</ejb-name> <method-name>*</method-name> </method> </method-permission> <method-permission> <role-name>InternalUser</role-name> <method> <ejb-name>PrivateSession</ejb-name> <method-name>*</method-name> </method> </method-permission> <method-permission> <role-name>Coder</role-name> <method> <ejb-name>PublicSession</ejb-name> <method-name>create</method-name> </method> <method> <ejb-name>PublicSession</ejb-name> <method-name>remove</method-name> </method> </method-permission> <method-permission> <unchecked/> <method> <ejb-name>PublicSession</ejb-name> <method-name>noop</method-name> </method> </method-permission> <exclude-list> <description>Methods that cannot be used in this deployment</description> <method> <ejb-name>PublicSession</ejb-name> <method-name>restricted</method-name> </method> </exclude-list> </assembly-descriptor> </ejb-jar>
Web application security constraints
In a Web application, security is defined by the roles allowed access to content; a URL pattern identifies the protected content. For example, the
descriptor fragment below indicates that any URL lying under the Web application's
path requires an
<web-app> ... <security-constraint> <web-resource-collection> <web-resource-name>Secure Content</web-resource-name> <url-pattern>/restricted/*</ url-pattern></ <web-resource-collection> <auth-constraint> <role-name>AuthorizedUser</role-name> </auth-constraint> </security-constraint> ... <security-role> <description>The role required to access restricted content</description> <role-name>AuthorizedUser</role-name> </security-role> </web-app>
elements are equivalent to their EJB counterparts.
Specify the security domain in JBoss
The J2EE security elements I have covered describe only the security requirements from the application's perspective. Since J2EE security elements declare logical roles, the application deployer maps the roles from the application domain onto the deployment environment. The EJB specification omits these application-server-specific details. In JBoss, mapping the application roles onto the deployment environment entails specifying a security manager that implements the J2EE security model. Figure 3 shows the JBoss-specific EJB and Web application deployment descriptor's security-related elements.
element to identify the Java Naming and Directory Interface (JNDI) name of the security manager interface implementation that JBoss uses for the EJB and Web containers. You may specify
as an EJB-level element to only set security for one or more EJBs when
is not a top-level element, or when
is a top-level element and you want to override it. The
element identifies a custom security interceptor that allows per-request security checks outside the scope of the EJB declarative security model without embedding security logic into the EJB implementation. I won't go into detail about that JBoss-specific feature, as this article focuses on using JAAS to implement the standard declarative security model. A JBoss security manager implementation requires the
interfaces presented in Figure 4.
For the remainder of this article, I focus on the JBossSX
org.jboss.security.plugins.JaasSecurityManager, a JAAS-based implementation of the security manager interfaces. But first, I'll present a brief introduction to JAAS.
What is JAAS?
The JAAS 1.0 API consists of a set of Java packages for the user authentication and authorization. It implements a Java version of the standard Pluggable Authentication Module (