Integrate security infrastructures with JBossSX

JBossSX uses JAAS to integrate application servers and security infrastructures

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

ejb-jar.xml

and

web.xml

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

ejb-jar.xml

and

web.xml

deployment descriptors. Figures 1 and 2 illustrate the security-related elements in the EJB 2.0 and Servlet 2.2 deployment descriptors, respectively.

Figure 1. The EJB 2.0 deployment descriptor security elements Click on thumbnail to view full-size image.

Together, these security elements define the bean author and application assembler's view of an enterprise application's security requirements.

Figure 2. The Servlet 2.2 deployment descriptor security elements Click on thumbnail to view full-size image.

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

security-role-ref

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

EJBContext.getCallerPrincipal()

method as a

java.security.Principal

instance. Using the

EJBContext.isCallerInRole(String)

method, an EJB checks if a caller is in a role that has been declared with a

security-role-ref

element. The

role-name

element value must link to a security role in the assembly-descriptor section of

ejb-jar.xml

through the

role-link

element. You typically use

isCallerInRole()

to perform a security check that cannot be defined using method permissions. See section 21.2.5 of the

EJB 2.0 Specification PFD2

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

security-identity

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

security-identity

element to indicate that the current caller's identity should be propagated by using a

use-caller-identity

element as

security-identity

's value. Alternatively, the application assembler can use the

run-as

element with the

security-identity

's value as

role-name

to specify that EJB calls are performed with the security role given by the

role-name

value. Note that this does not change the caller's identity as seen by

EJBContext.getCallerPrincipal()

. Rather, the caller's security roles are set to the single role specified by the

run-as/role-name

element value. You can use a

run-as

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

run-as/role-name

element value for EJBs that use the internal EJB.

Assembly descriptor security roles

The security role referenced by either

security-role-ref

or

security-identity

elements needs to map to one of the application's declared roles. An application assembler defines logical security roles by adding

security-role

elements to the

assembly-descriptor

element. In JBoss, a

security-role

is only used to map an EJB

security-role-ref/role-name

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

security-role

s to identify method permissions. Therefore, you should specify a

security-role

element for every role used in the

method-permission

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

method-permission

elements. Each

method-permission

element contains one or more

role-name

elements that define the logical roles allowed access to one or more EJB methods as identified by

method

elements. With EJB 2.0, you can now specify the

unchecked

element instead of the

role-name

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

exclude-list

element. For method syntax, see section 21.3.2 of the

EJB 2.0 Specification PFD2

.

An example EJB deployment descriptor

The following

ejb-jar.xml

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

web.xml

descriptor fragment below indicates that any URL lying under the Web application's

/restricted

path requires an

AuthorizedUser

role:

 <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>

The

security-role-ref

and

security-role

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.

Figure 3. The JBoss-specific EJB and Web deployment descriptor security elements Click on thumbnail to view full-size image.

Use the

security-domain

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

security-domain

as an EJB-level element to only set security for one or more EJBs when

security-domain

is not a top-level element, or when

security-domain

is a top-level element and you want to override it. The

security-proxy

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

org.jboss.security.EJBSecurityManager

and

org.jboss.security.RealmMapping

interfaces presented in Figure 4.

Figure 4. JBoss security manager interfaces Click on thumbnail to view full-size image.

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 (

PAM

1 2 3 4 5 Page
Join the discussion
Be the first to comment on this article. Our Commenting Policies
See more