SecureAWebApplicationInJBoss

Securing a Web Application in JBoss AS

 

Securing web resources basically involves setting some stuff in the web deployment descriptor, and in jboss-web.xml.  You also have to do a little prep work to the server itself to configure a security domain for JBoss SX.  These instructions assume that you have JBoss AS installed, and you have a server instance created with at least Tomcat included.  The "default" instance is a good choice here.  The variable ${jboss.dist} refers to the location you extracted/installed JBoss AS to, and ${server.name} cooresponds to the name of the server instance you are configuring for security.

 

Prepare JBoss SX:

 

1. Open the ${jboss.dist}/server/${server.name}/conf/login-config.xml file.

 

This file sets up the configuration for the security domains available to applications running in the server.  The file already has a few domains in there for some example/default resources, so you might want to look to those for inspiration.  JBoss SX uses JAAS for the underlying security infrastructure, and JAAS uses a class called a "login module" to interact with a security store for authenticating credentials.  This file basically hooks up a security domain (just a name really) to a JAAS login module.  JBoss AS comes packed with a few different login modules which you can find more information about on the JBoss SX wiki page at JBossSX.

 

The easiest login module to start with is the UsersRolesLoginModule.  This login module allows you to specify user names, passwords and roles in a simple property file.  Obviously, this module isn't one of the more secure modules, so you probably would want to use something like LDAP to store/lookup credentials in production.

 

2.  Copy the "jmx-console" domain policy as a starting point.

 

The "jmx-console" security domain policy contains the basics for configuring a UsersRolesLoginModule based security domain.  Here is a copy of that section:

     <application-policy name = "jmx-console">
          <authentication>
               <login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule"
             flag = "required">
                    <module-option name="usersProperties">props/jmx-console-users.properties</module-option>
                    <module-option name="rolesProperties">props/jmx-console-roles.properties</module-option>
               </login-module>
          </authentication>
     </application-policy>

Copy this section to the bottom of the file, and change the "name" attribute on the application-policy attribute to "my-web".  Also, change the "userProperties" module-option text value to be "props/my-web-users.properties", and the "roleProperties" module-option text value to be "props/my-web-roles.properties".  Save the login-config.xml file.

 

The "name" attribute on the "application-policy" element specifies the name of the security domain.  This name is important because it is what will be used to tie the security domain to the web application later.  The "login-module" element specifies the login module that this domain will use.  You can actually have multiple "login-module" elements to have multi-level authentication, but we'll stick to one for this simple case.  The "flag" attribute on the login-module element specifies how to handle failed authentications from this module, and how it interacts with other modules.  The "required" value is what you would want for a single login module, but you can refer to the DTD for the login-config.xml file for more info about the other options.  Finally, the "module-option" elements specify some values to pass into the login module's "initialize" method.  These values are passed in as a name-value map to that method.  In the case of the UsersRolesLoginModule, we need to tell the module what properties files to use for looking up user information (usersProperties), and what file to use for looking up role information (rolesProperties).  These paths are relative to the ${jboss.dist}/server/${server.name}/conf directory.

 

3. In the ${jboss.dist}/server/conf/props directory, copy the jmx-console-users.properties into a new file called my-web-users.properties, and copy the jmx-console-roles.properties into a new file called my-web-roles.properties.

 

Opening the my-web-users.properties file, you will see a single entry like this:

"admin=admin".  When a user logs into this security domain, the login module will examine the properties data in this file for known users.  The structure of the entries in this file is "username=password".  Let's add a new entry to the file for your own user by pasting "chris=secure" on a new line below the "admin=admin" line in the file.  Save this file.

 

Next, open the my-web-roles.properties file, and you should see an line like the following: "admin=JBossAdmin,HttpInvoker".  The entries in this file define what roles a user has associated with their account when they login.  The form of these entries is "username=Role1,Role2,..." where the username is the user you wish to assign roles to, and the Roles entries are a comma separated list of roles to assign to that user.  Add a new entry to this file by pasting "chris=WebAppUser" on a new line below the "admin=...." line.  Save this file.

 

Securing the Web Application

 

Note:

Attached is a sample application that can be used to test out securing a web application.  There are two files that need to be added/modified in your web application to attach it to the security domain we defined in the previous steps.  The web.xml and jboss-web.xml file contain commented out versions of the text to add to a web application that are covered in the next two steps.  Also included, is a simple index.jsp that outputs the name of the authenticated JAAS Subject via HttpServletRequest.getRemoteUser().

 

1. Configure the web application for security by adding constraints to the web deployment descriptor.

 

You need to modify the web.xml in the WEB-INF directory of the web application you are securing to add in the following:

     <security-constraint>
          <web-resource-collection>
               <web-resource-name>All resources</web-resource-name>
               <description>Protects all resources</description>
               <url-pattern>/*</url-pattern>
          </web-resource-collection>
          <auth-constraint>
               <role-name>WebAppUser</role-name>
          </auth-constraint>
     </security-constraint>
   
     <security-role>
          <role-name>WebAppUser</role-name>
     </security-role>
      
     <login-config>
          <auth-method>BASIC</auth-method>
          <realm-name>Test Realm</realm-name>
     </login-config>

The "security-constraint" section is what is used to define what resources in the web application are protected.  You can have multiple security-constraint elements in the web.xml that have different protections for different resources.  You have to have at least on web-resource-collection element to specify what this constraint it protecting.  The "url-pattern" element specifies the URL pattern to protect.  The example above protects all resources in the web application.  The auth-contstraint element specifies which roles have access to the protected resource.  The example just specifies one role, but multiple roles can be included by specifying additional role-name elements.  This role name needs to match the name of the role you specified in the my-web-roles.properties file.  There are ways to have a level of indirection with this role name by using the "security-role-ref" element instead.  Finally, the "login-config" element specifies how authentication occurs with the web application.  The "auth-method" element specifies how the browser gets credentials from the user.  The spec defines "BASIC", "DIGEST", "FORM", and "CLIENT-CERT" as the possible methods to retrieve data from the browser user.  The example uses "BASIC" since it is the simplest, but this method shouldn't be used in a production app unless you are also using SSL/TLS since user names and passwords are transmitted in clear text over the network.  The "realm-name" element just specifies the authentication realm name that is given to the browser for authentication.  This realm is just shown to a user when the authentication dialog is presented.

 

2. Configure the jboss-web.xml file to point to the "my-web" application.

 

Add/edit the jboss-web.xml in the WEB-INF directory of the web application you are securing to add the following in the "jboss-web" element:

<security-domain>java:/jaas/my-web</security-domain>

This element tells JBoss AS to connect the web application to the "my-web" security domain we defined in the login-config.xml file earlier.  JBoss AS exposes security domains via JNDI by prepending "java:/jaas/" to the name element in the application-policy element in the login-config.xml file.

 

3. Start up the application server, navigate to your application.

 

The browser should prompt you for username and password.  Enter "chris" for the username, and "secure" for the password.  You should then be allowed access to the web application.  You can verify this by closing the browser, opening it back up and navigating back to your protected application.  When the browser prompts you, you can either enter no credentials, or use the "admin" user account that was in the file originally (password: admin), and see that the web application won't be presented because you didn't log in with a user that had the "WebAppUser" role.

 

Related:

JavaWorld JAAS article by Scott Stark:

http://prdownloads.sourceforge.net/jboss/jaashowto-32x.zip?download