Integrate security infrastructures with JBossSX

JBossSX uses JAAS to integrate application servers and security infrastructures

1 2 3 4 5 Page 4
Page 4 of 5
  • You need the Ant build tool. If you don't already have it, see the Ant homepage.
  • Next, download the JBoss/Tomcat 2.4.x bundle from Sourceforge and unarchive it. At the time of this writing, the current JBoss/Tomcat bundle is JBoss-2.4.0.26_Tomcat-3.2.3.zip; it unarchives to create a JBoss-2.4.0_Tomcat-3.2.3 directory.
  • Next, download the Examples archive and unarchive them.
  • Edit the dist.root property that specifies the JBoss/Tomcat bundle location in the build.xml file, or override the property on the command line to Ant by creating an .ant.properties file in the examples root directory. The default location is /tmp/JBoss-2.4.0_Tomcat-3.2.3, so if you unarchive the JBoss/Tomcat bundle in your /tmp directory, you're ready to go.
  • Build and deploy the example ears by running Ant within the examples directory. Your output should look something like this:
     examples 210>ant
     Buildfile: build.xml
     
     validate:
     
     fail_if_not_valid:
     
     init:
          [echo] Using jboss.dist=/tmp/JBoss-2.4.0_Tomcat-3.2.3/jboss
          [echo] Using classpath=/tmp/JBoss-2.4.0_Tomcat-3.2.3/...
     
     compile:
         [mkdir] Created dir: /home/starksm/examples/build/classes
         [javac] Compiling 7 source files to /home/starksm/examples/build/classes
     
     jar1:
         [mkdir] Created dir: /home/starksm/examples/build/META-INF
          [copy] Copying 1 file to /home/starksm/examples/build/META-INF
          [copy] Copying 1 file to /home/starksm/examples/build/META-INF
           [jar] Building jar: /home/starksm/examples/build/ssbean1.jar
     
     war1:
         [mkdir] Created dir: /home/starksm/examples/build/web/WEB-INF/classes/org/jboss/docs/jaas/howto
          [copy] Copying 1 file to /home/starksm/examples/build/web/WEB-INF
          [copy] Copying 1 file to /home/starksm/examples/build/web/WEB-INF
          [copy] Copying 1 file to /home/starksm/examples/build/web/WEB-INF/classes/org/jboss/docs/jaas/howto
           [jar] Building jar: /home/starksm/examples/build/tutorial1.war
     
     ear1:
          [copy] Copying 1 file to /home/starksm/examples/build/META-INF
           [jar] Building jar: /home/starksm/examples/build/tutorial1.ear
     
     ...
     
     ears:
          [copy] Copying 1 file to /tmp/JBoss-2.4.0_Tomcat-3.2.3/jboss/deploy
          [copy] Copying 1 file to /tmp/JBoss-2.4.0_Tomcat-3.2.3/jboss/deploy
         [mkdir] Created dir: /tmp/JBoss-2.4.0_Tomcat-3.2.3/jboss/conf/jaas_howto
          [copy] Copying 19 files to /tmp/JBoss-2.4.0_Tomcat-3.2.3/jboss/conf/jaas_howto
          [copy] Copying 1 file to /tmp/JBoss-2.4.0_Tomcat-3.2.3/jboss/conf/jaas_howto
    
    If you see something similar to this:
     examples 212>ant
     Buildfile: build.xml
     
     validate:
     
     fail_if_not_valid:
     
     BUILD FAILED
     
     /home/starksm/examples/build.xml:34: jboss.dist=/usr/local/JBoss-2.4.0_Tomcat-3.2.3/jboss is not a valid JBoss dist directory
    
    you need to correct the dist.root property's value in the Ant build.xml file in the examples directory as indicated in the previous step.
  • Now start the JBoss server with the jaas_howto configuration, which contains the JAAS login configuration file and was created by the Ant build process. To start JBoss, go to the jboss/bin directory and execute the run.sh or run.bat script as appropriate for your operating system, passing in the jaas_howto config name. Here's an example from a Linux system with key output emphasized:
     bin 358>./run.sh jaas_howto
     JBOSS_CLASSPATH=:run.jar:../lib/crimson.jar
     jboss.home = /tmp/JBoss-2.4.0_Tomcat-3.2.3/jboss
     Using JAAS LoginConfig: file:/tmp/JBoss-2.4.0_Tomcat-3.2.3/jboss/conf/jaas_howto/auth.conf
     Using configuration "jaas_howto"
     [root] Started Log4jService, config=file:/tmp/JBoss-2.4.0_Tomcat-3.2.3/jboss/conf/jaas_howto/log4j.properties
     [Info] Java version: 1.3.1,Sun Microsystems Inc.
     [Info] Java VM: Java HotSpot(TM) Server VM 1.3.1-b24,Sun Microsystems Inc.
     [Info] System: Linux 2.4.3-12,i386
     ...
     [Container factory] Deployed application: file:/tmp/JBoss-2.4.0_Tomcat-3.2.3/jboss/tmp/deploy/Default/tutorial1.ear
     [J2EE Deployer Default] Starting module tutorial1.war
     [EmbeddedTomcatSX] deploy, ctxPath=/jaas-example1, warUrl=file:/tmp/JBoss-2.4.0_Tomcat-3.2.3/jboss/tmp/deploy/Default/tutorial1.ear/web1003/
     [J2EE Deployer Default] J2EE application: file:/tmp/JBoss-2.4.0_Tomcat-3.2.3/jboss/deploy/tutorial1.ear is deployed.
     
     [Service Control] Started 28 services
     [Default] JBoss 2.4 BETA(Rel_2_4_0_25) Started in 0m:15s
    

The tutorial1.ear contents

tutorial1.ear

consists of a single Webpage, a secured servlet, an unsecured servlet, and two secured stateless session beans. As the servlet and session bean code is trivial, I'll leave its inspection as an exercise for you. The interesting aspect of the example is the deployment descriptors' security-related elements and the configuration of the JAAS login module associated with the security domain.

tutorial1.ear

's contents are shown below with the security-related files

emphasized:

 tutorial1.ear 
 + META-INF
 |-- MANIFEST.MF
 |-- application.xml
 + ssbean1.jar
 |-- + META-INF
 |----- ejb-jar.xml
 |----- jboss.xml
 |-- + org/jboss/docs/jaas/howto
 |----- Session.class
 |----- SessionHome.class
 |----- PrivateSessionBean.class
 |----- PublicSessionBean.class
 |-- roles.properties
 |-- users.properties
 + tutorial1.war
 |-- + WEB-INF
 |----- web.xml
 |----- jboss-web.xml
 |----+ classes/org/jboss/docs/jaas/howto
 |------ EJBServlet.class
 |-- index.html

We'll look at each file in turn.

The tutorial1.ear/ssbean1.jar/META-INF/ejb-jar.xml descriptor

The following

ejb-jar.xml

deployment descriptor declares the tutorial EJBs and their security requirements:

 <?xml version = "1.0" encoding = "UTF-8"?>
 <!DOCTYPE ejb-jar
   PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 1.1//EN"
   "http://java.sun.com/dtd/ejb-jar_2_0.dtd">
 
 <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.PublicSessionBean</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-role-ref>
         <role-name>EchoUser</role-name>
         <role-link>Echo</role-link>
       </security-role-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.PrivateSessionBean</ejb-class>
       <session-type>Stateful</session-type>
       <transaction-type>Container</transaction-type>
       <security-role-ref>
         <role-name>InternalUser</role-name>
         <role-link>InternalUser</role-link>
       </security-role-ref>
     </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>

Items of note include:

  • The security-role-ref element is where the PublicSession bean declares an EchoUser role name, which links to the Echo role name. That element indicates that the PublicSession bean queries the EJBContext.isCallerInRole with a EchoUser role name string.
  • The security-identity/run-as/role-name InternalUser declaration indicates that a principal with a role named InternalUser handles any EJB calls made by the PublicSession bean.
  • The PrivateSession bean declares an InternalUser role name to indicate that the bean queries the EJBContext.isCallerInRole with an InternalUser role name string.
  • In the assembly-descriptor section, logical roles of Echo, Coder, and InternalUser are declared using security-role elements.
  • The Echo role receives permission to access any method in the PublicSession bean in the first method-permission element.
  • The InternalUser role receives permission to access any PrivateSession bean method in the second method-permission element.
  • The fourth method-permission element indicates that any authenticated user can call the PublicSession noop method with the unchecked element instead of a role-name element.
  • The exclude-list element declares that no one can call the PublicSession restricted method.

The tutorial1.ear/ssbean1.jar/META-INF/jboss.xml descriptor

The code below is the JBoss-server-specific EJB deployment descriptor:

 <?xml version="1.0" encoding="UTF-8"?>
 
 <jboss>
   <!-- All bean containers use this security manager by default -->
   <security-domain>java:/jaas/example1</security-domain>
 
   <enterprise-beans>
     <session>
       <ejb-name>PublicSession</ejb-name>
       <jndi-name>example1/PublicSession</jndi-name>
     </session>
 
     <session>
       <ejb-name>PrivateSession</ejb-name>
       <jndi-name>example1/PrivateSession</jndi-name>
     </session>
   </enterprise-beans>
 
 </jboss>

This descriptor indicates that the security manager located at the JNDI name

java:/jaas/example1

secures all EJBs in the

ssbean1.jar

. The JNDI name's final component (

example1

) determines which login modules are associated with the security domain.

The tutorial1.ear/ssbean1.jar/roles.properties, users.properties files

The

org.jboss.security.auth.spi.UsersRolesLoginModule

custom JAAS login module shipped with the JBossSX framework uses the

roles.properties

and

users.properties

files. This simple login module uses Java properties format files for mapping usernames to passwords and usernames to roles names. The

roles.properties

file maps a username to one or more role names using the format

username[.RoleGroup]=role1_name[,role2_name,...]

. A

RoleGroup

names the

Group

that will be created to hold given roles. With no specified

RoleGroup

, it defaults to

Roles

. Here's the

roles.properties

file for the example:

 # roles.properties
 java=Echo
 duke=Java,Coder
 java.CallerPrincipal=caller_java
 duke.CallerPrincipal=caller_duke

The code above maps the username

java

to the role name

Echo

under the

Roles RoleGroup

, and the role name

caller_java

under the

CallerPrincipal RoleGroup

. The

users.properties

file maps a username to a user password. Here's the

users.properties

file for the example:

 # users.properties
 java=echoman
 duke=javaman

The above code maps the username

java

to the password

echoman

.

The tutorial1.ear/tutorial1.war/WEB-INF/web.xml descriptor

The following

web.xml

deployment descriptor declares the tutorial servlets and their EJB references and security requirements:

 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE web-app
   PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
   "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">
 
 <web-app>
 <!-- ### Servlets -->
   <servlet>
     <servlet-name>SecureServlet</servlet-name>
     <servlet-class>org.jboss.docs.jaas.howto.EJBServlet</servlet-class>
   </servlet>
   <servlet>
     <servlet-name>UnsecureServlet</servlet-name>
     <servlet-class>org.jboss.docs.jaas.howto.EJBServlet</servlet-class>
   </servlet>
   <servlet-mapping>
     <servlet-name>SecureServlet</servlet-name>
     <url-pattern>/restricted/SecureServlet</url-pattern>
   </servlet-mapping>
   <servlet-mapping>
     <servlet-name>UnsecureServlet</servlet-name>
     <url-pattern>/UnsecureServlet</url-pattern>
   </servlet-mapping>
 
 <!-- ### Security -->
   <security-constraint>
     <web-resource-collection>
       <web-resource-name>Restricted</web-resource-name>
       <description>Declarative security tests</description>
       <url-pattern>/restricted/*</url-pattern>
       <http-method>HEAD</http-method>
       <http-method>GET</http-method>
       <http-method>POST</http-method>
       <http-method>PUT</http-method>
       <http-method>DELETE</http-method>
     </web-resource-collection>
     <auth-constraint>
       <role-name>Echo</role-name>
     </auth-constraint>
     <user-data-constraint>
       <description>no description</description>
       <transport-guarantee>NONE</transport-guarantee>
     </user-data-constraint>
   </security-constraint>
 
   <login-config>
     <auth-method>BASIC</auth-method>
     <realm-name>JAAS Tutorial Servlets</realm-name>
   </login-config>
 
   <security-role>
     <description>A user allowed to invoke echo methods</description>
     <role-name>Echo</role-name>
   </security-role>
 
 <!-- ### EJB References (java:comp/env/ejb) -->
   <ejb-ref>
     <ejb-ref-name>ejb/SecuredEJB</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-ref>
   <ejb-ref>
     <ejb-ref-name>ejb/PrivateEJB</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-ref>
 
 </web-app> 

The security items of note include:

  • The security-constraint/web-resource-collection/url-pattern element declaration indicates that all content under /restricted must be secured for the indicated HTTP methods.
  • The auth-constraint/role-name element indicates that only users with an Echo role can access the content under /restricted.
  • The login-config/auth-method element with the BASIC value indicates that BASIC HTTP authorization will authenticate users attempting to access content under /restricted.
  • The SecureServlet requires authenticated access, since its servlet-mapping/url-pattern element is under the /restricted path.

The tutorial1.ear/tutorial1.war/WEB-INF/jboss-web.xml descriptor

Here is the JBoss-server-specific Web application deployment descriptor:

 <?xml version="1.0" encoding="UTF-8"?>
 
 <jboss-web>
   <security-domain>java:/jaas/example1</security-domain>
 
   <ejb-ref>
     <ejb-ref-name>ejb/SecuredEJB</ejb-ref-name>
     <jndi-name>example1/PublicSession</jndi-name>
   </ejb-ref>
   <ejb-ref>
     <ejb-ref-name>ejb/PrivateEJB</ejb-ref-name>
     <jndi-name>example1/PrivateSession</jndi-name>
   </ejb-ref>
 </jboss-web> 

This code indicates that the security manager located at the JNDI name

java:/jaas/example1

handles security for all secured Web content. Since the

security-domain

element matches that used by the

jboss.xml

deployment descriptor, the same security manager secures the ear EJBs and Web content.

The jboss/conf/jaas_howto/auth.conf login configuration file

1 2 3 4 5 Page 4
Page 4 of 5