Using the database login module

A database security domain follows the same logic exposed in the earlier example; just, it stores the credentials within the database. In order to run this example, we are referring to a MySqlDS datasource which we reated earlier in Chapter 3, Configuring Enterprise Services:

<security-domain name=”mysqldomain” cache-type=”default”>
<login-module code=”Database” flag=”required”>
<module-option name=”dsJndiName”
<module-option name=”principalsQuery” value=”select
passwd from USERS where login=?”/>
<module-option name=”rolesQuery” value=”select role,
‘Roles’ from USER_ROLES where login=?”/>
In order to get working with this configuration, you have first have to create the required tables and insert some sample data in it:

INSERT into USERS values(‘admin’, ‘admin’)
INSERT into USER_ROLES values(‘admin’, ‘Manager’)

As you can see, the admin user will map again to the Manager role. One caveat of this configuration is that it uses clear-text passwords in the database, so before rolling this module production you should consider adding additional security to your login module. Let’s see how to do this in the next section.

Encrypting passwords

Storing passwords in the database as clear-text string is not considered a good practice; as a matter of fact, a database has even more potential security holes then a regular file system. Think about, for example, a DBA which added a public synonym for some tables, forgetting that one of those tables was holding sensitive information such as the application passwords! You need to be sure that no potential attackers will ever be able to deliver the following query:


Fortunately, securing application passwords is relatively easy: you can add a few extra options to your login module, specifying that the stored passwords are encrypted using a message digest algorithm. For example, in the mysqlLogin module, you should add the following highlighted options at the end:

<login-module code=”Database” flag=”required”>
<module-option name=”dsJndiName” value=”java:/MySqlDS”/>
<module-option name=”principalsQuery” value=”select passwd from
USERS where login=?”/>
<module-option name=”rolesQuery” value=”select role, ‘Roles’
from USER_ROLES where login=?”/>
<module-option name=”hashAlgorithm” value=”MD5″/>
<module-option name=”hashEncoding” value=”BASE64″/>
<module-option name=”hashStorePassword” value=”true”/>
Here, we have specified that the password will be hashed against an MD5 hash algorithm; you can alternatively use any other algorithm allowed by your JCA Provider, like SHA, for example.

For the sake of completeness, we include here a small application, which uses the java.security.MessageDigest and the org.jboss.security.Base64Util class to generate the base-64 hashed password to be inserted in the database:

public class Hash {
public static void main(String[] args)
String password = args[0];
MessageDigest md = null;
md = MessageDigest.getInstance(“MD5”);
catch(Exception e)
byte[] passwordBytes = password.getBytes();
byte[] hash = md.digest(passwordBytes);
String passwordHash =
System.out.println(“password hash: “+passwordHash);

Running the main program with admin as argument, generates the hash X8oyfUbUbfqE9IWvAW1/3. This hash will be your updated password for the admin user into our database:


Using an LDAP login module

The Lightweight Directory Access Protocol (LDAP) is the de facto standard for
providing directory services to applications. An LDAP server can provide a central
directory information for:

  • User credentials (login and password)
  • User directory information (such as names and e-mail addresses)
  • Web directories

The action in LDAP takes place around a data structure known as an entry . An entry has a set of named component parts called attributes that hold the data for that entry. To use database terms, they are like the fields in a database record.

An entry’s content and structure are defined by its object. Its object class defines an entry’s content and structure. The object class (along with server and user settings) specifies which attributes must and may exist in that particular entry.

All entries stored in an LDAP directory have a unique Distinguished Name , or DN. The DN for each LDAP entry is composed of two parts: the Relative Distinguished Name (RDN) and the location within the LDAP directory where the record resides.

In practice, the RDN is the portion of your DN that is not related to the directory tree structure, and is in turn, composed of one or several attribute name/value pairs. Let’s see a concrete example in an organization:

database login module

In the previous diagram, “cn=John Smith” (where cn stands for “common name”) could be an RDN. The attribute name is cn and the value is John Smith.

On the other hand, the DN for John Smith would be: cn=John Smith, ou=Marketing, o=Acme, c=US (where ou is short for organizational unit, o is short for organization, and c is for country).

Connecting LDAP to JBoss AS

That being said, connecting to JBoss AS and LDAP can be done by means of several LDAP login modules. The first and obvious thing we need is a running instance of an LDAP server available. Today, there is a huge number of LDAP servers (both commercial and open source) available, and maybe, you have already configured one to run in your company. Just in case you don’t have one, or simply don’t want to add sample data to it, we suggest you having a look at Apache Directory Service (http://directory.apache.org/), which is an excellent solution for getting started with LDAP but also for building complex directory infrastructures.

Once installed, we suggest you using the Apache Directory Studio (available at the same link) to create a directory infrastructure quickly. The simplest way to create a directory from scratch is by means of an LDAP’S Data Interchange Format File (LDIF) file. Within this file, you can mention all entries which will be loaded by the
LDAP engine.

Here’s a basic LDIF file we will use:
dn: dc=example,dc=com
objectclass: top
objectclass: dcObject
objectclass: organization
dc: example
o: MCC
dn: ou=People,dc=example,dc=com
objectclass: top
objectclass: organizationalUnit
ou: People
dn: uid=admin,ou=People,dc=example,dc=com
objectclass: top
objectclass: uidObject
objectclass: person
uid: admin
cn: Manager
sn: Manager
userPassword: secret
dn: ou=Roles,dc=example,dc=com
objectclass: top
objectclass: organizationalUnit
ou: Roles
dn: cn=Manager,ou=Roles,dc=example,dc=com
objectClass: top
objectClass: groupOfNames
cn: Manager
description: the JBossAS7 group
member: uid=admin,ou=People,dc=example,dc=com

Once you have imported this information into the LDAP server, you will end up with the following small directory:


Within this directory, we have just one user registered as admin, belonging to the Manager role, just like other login modules we have shown in the earlier sections.

Now we will configure the LDAP connection on JBoss AS 7. For our purpose, we will use the LdapExtended login module implementation that uses searches for locating both the user to bind for authentication and the associated roles. The roles query will follow distinguished names (DNs) recursively to navigate a hierarchical role structure.

<login-module code=”LdapExtended” flag=”required”>
<module-option name=”java.naming.factory.initial”
<module-option name=”java.naming.provider.url”
<module-option name=”java.naming.security.authentication”
<module-option name=”bindDN” value=”uid=admin,ou=system”/>
<module-option name=”bindCredential” value=”secret”/>
<module-option name=”baseCtxDN”
<module-option name=”baseFilter” value=”(uid={0})”/>
<module-option name=”rolesCtxDN”
<module-option name=”roleFilter” value=”(member={1})”/>
<module-option name=”roleAttributeID” value=”cn”/>
<module-option name=”searchScope” value=”ONELEVEL_SCOPE”/>
<module-option name=”allowEmptyPasswords” value=”true”/>

The following is a brief description of the module properties:

bindDN: The DN used to bind against the LDAP server for the user and roles queries, in our case “uid=admin,ou=system”.
baseCtxDN: It is the fixed DN of the context to start the user search from. In our example it is “ou=People,dc=example,dc=com.”
baseFilter: It is a search filter used to locate the context of the user to authenticate. The input username/userDN as obtained from the login module will be substituted into the filter anywhere a “{0}” expression is seen.

rolesCtxDN: It is the fixed DN of the context to search for user roles. Consider that this is not the Distinguished Name of where the actual roles are; rather, this is the DN of where the objects containing the user roles are.

roleFilter: It is a search filter used to locate the roles associated with the authenticated user. An example search filter that matches on the input username is ” (member={0}).” An alternative that matches on the authenticated userDN is ” (member={1}).”

roleAttributeID: It is the name of the role attribute of the context which corresponds to the name of the role.

searchScope: It sets the search scope to one of the strings. ONELEVEL_SCOPE searches directly under the named roles context.

allowEmptyPasswords: It is a flag indicating if empty(length==0) passwords should be passed to the LDAP server.

0 Responses on Using the database login module"

Leave a Message

Your email address will not be published. Required fields are marked *

Copy Rights Reserved © Mindmajix.com All rights reserved. Disclaimer.