The LDAP login module enables you to perform authentication by checking the incoming credentials against user data stored in a central X.500 directory server. For systems that already have an X.500 directory server in place, this means that you can rapidly integrate Fuse Message Broker with the existing security database and user accounts can be managed using the X.500 system.
Example 3.9 shows an example of a login
entry for the LDAP login module, connecting to a directory server with the URL,
ldap://localhost:10389
.
Example 3.9. LDAP Login Entry
LDAPLogin { org.apache.activemq.jaas.LDAPLoginModule required debug=true initialContextFactory=com.sun.jndi.ldap.LdapCtxFactory connectionURL="ldap://localhost:10389" connectionUsername="uid=admin,ou=system" connectionPassword=secret connectionProtocol="" authentication=simple userBase="ou=User,ou=ActiveMQ,ou=system" userSearchMatching="(uid={0})" userSearchSubtree=false roleBase="ou=Group,ou=ActiveMQ,ou=system" roleName=cn roleSearchMatching="(member=uid={1})" roleSearchSubtree=false ; };
The preceding login entry, LDAPLogin
, is configured to search for users
under the ou=User,ou=ActiveMQ,ou=system
level in the Directory Information
Tree (DIT). For example, an incoming username, jdoe
, would match the entry
whose DN is uid=jdoe,ou=User,ou=ActiveMQ,ou=system
.
The LDAP login entry supports the following options:
debug
—boolean debugging flag. Iftrue
, enable debugging. This is used only for testing or debugging. Normally, it should be set tofalse
, or omitted.initialContextFactory
—(mandatory) must always be set tocom.sun.jndi.ldap.LdapCtxFactory
.connectionURL
—(mandatory) specify the location of the directory server using an ldap URL,ldap://
. You can optionally qualify this URL, by adding a forward slash,Host
:Port
/
, followed by the DN of a particular node in the directory tree. For example,ldap://ldapserver:10389/ou=system
.authentication
—(mandatory)specifies the authentication method used when binding to the LDAP server. Can take either of the values,simple
(username and password) ornone
(anonymous).Note Simple Authentication and Security Layer (SASL) authentication is currently not supported.
connectionUsername
—(optional)the DN of the user that opens the connection to the directory server. For example,uid=admin,ou=system
.Directory servers generally require clients to present username/password credentials in order to open a connection.
connectionPassword
—(optional)the password that matches the DN fromconnectionUsername
. In the directory server, in the DIT, the password is normally stored as auserPassword
attribute in the corresponding directory entry.connectionProtocol
—(mandatory)currently, the only supported value is a blank string. In future, this option will allow you to select the Secure Socket Layer (SSL) for the connection to the directory server.Note This option must be set explicitly to an empty string, because it has no default value.
userBase
—(mandatory)selects a particular subtree of the DIT to search for user entries. The subtree is specified by a DN, which specifes the base node of the subtree. For example, by setting this option toou=User,ou=ActiveMQ,ou=system
, the search for user entries is restricted to the subtree beneath theou=User,ou=ActiveMQ,ou=system
node.userSearchMatching
—(mandatory)specifies an LDAP search filter, which is applied to the subtree selected byuserBase
. Before passing to the LDAP search operation, the string value you provide here is subjected to string substitution, as implemented by thejava.text.MessageFormat
class. Essentially, this means that the special string,{0}
, is substituted by the username, as extracted from the incoming client credentials.After substitution, the string is interpreted as an LDAP search filter, where the LDAP search filter syntax is defined by the IETF standard, RFC 2254. A short introduction to the search filter syntax is available from Oracle's JNDI tutorial, Search Filters.
For example, if this option is set to
(uid={0})
and the received username isjdoe
, the search filter becomes(uid=jdoe)
after string substitution. If the resulting search filter is applied to the subtree selected by the user base,ou=User,ou=ActiveMQ,ou=system
, it would match the entry,uid=jdoe,ou=User,ou=ActiveMQ,ou=system
(and possibly more deeply nested entries, depending on the specified search depth—see theuserSearchSubtree
option).userSearchSubtree
—(optional)specify the search depth for user entries, relative to the node specified byuserBase
. This option can take boolean values, as follows:false
—(default) try to match one of the child entries of theuserBase
node (maps tojavax.naming.directory.SearchControls.ONELEVEL_SCOPE
).true
—try to match any entry belonging to the subtree of theuserBase
node (maps tojavax.naming.directory.SearchControls.SUBTREE_SCOPE
).
userRoleName
—(optional)specifies the name of the multi-valued attribute of the user entry that contains a list of role names for the user (where the role names are interpreted as group names by the broker's authorization plug-in). If you omit this option, no role names are extracted from the user entry.roleBase
—if you want to store role data directly in the directory server, you can use a combination of role options (roleBase
,roleSearchMatching
,roleSearchSubtree
, androleName
) as an alternative to (or in addition to) specifying theuserRoleName
option.This option selects a particular subtree of the DIT to search for role/group entries. The subtree is specified by a DN, which specifes the base node of the subtree. For example, by setting this option to
ou=Group,ou=ActiveMQ,ou=system
, the search for role/group entries is restricted to the subtree beneath theou=Group,ou=ActiveMQ,ou=system
node.roleName
—(optional)specifies the attribute type of the role entry that contains the name of the role/group. If you omit this option, the role search feature is effectively disabled.roleSearchMatching
—(mandatory)specifies an LDAP search filter, which is applied to the subtree selected byroleBase
. This works in a similar manner to theuserSearchMatching
option, except that it supports two substitution strings, as follows:{0}
substitutes the full DN of the matched user entry (that is, the result of the user search). For example, for the user,jdoe
, the substituted string could beuid=jdoe,ou=User,ou=ActiveMQ,ou=system
.{1}
substitutes the received username. For example,jdoe
.
For example, if this option is set to
(member=uid={1})
and the received username isjdoe
, the search filter becomes(member=uid=jdoe)
after string substitution (assuming ApacheDS search filter syntax). If the resulting search filter is applied to the subtree selected by the role base,ou=Group,ou=ActiveMQ,ou=system
, it matches all role entries that have amember
attribute equal touid=jdoe
(the value of amember
attribute is a DN).Note This option must always be set, even if role searching is disabled, because it has no default value.
Tip If you use OpenLDAP, the syntax of the search filter is
(member:=uid=jdoe)
.roleSearchSubtree
—(optional)specify the search depth for role entries, relative to the node specified byroleBase
. This option can take boolean values, as follows:false
—(default) try to match one of the child entries of theroleBase
node (maps tojavax.naming.directory.SearchControls.ONELEVEL_SCOPE
).true
—try to match any entry belonging to the subtree of theroleBase
node (maps tojavax.naming.directory.SearchControls.SUBTREE_SCOPE
).
Add user entries under the node specified by the userBase
option. When
creating a new user entry in the directory, choose an object class that supports the
userPassword
attribute (for example, the person
or
inetOrgPerson
object classes are typically suitable). After creating the
user entry, add the userPassword
attribute, to hold the user's password.
If you want to store role data in dedicated role entries (where each node represents a
particular role), create a role entry as follows. Create a new child of the
roleBase
node, where the objectClass
of the child is
groupOfNames
. Set the cn
(or whatever attribute type is
specified by roleName
) of the new child node equal to the name of the
role/group. Define a member
attribute for each member of the role/group,
setting the member value to the DN of the corresponding user (where the DN is specified
either fully, uid=jdoe,ou=User,ou=ActiveMQ,ou=system
, or partially,
uid=jdoe
).
If you want to add roles to user entries, you would need to customize the directory schema, by adding a suitable attribute type to the user entry's object class. The chosen attribute type must be capable of handling multiple values.
The simplest way to make the login configuration available to JAAS is to add the
directory containing the file, login.config
, to your CLASSPATH. For more
details, see Location of the login configuration file.
To enable the JAAS username/password authentication plug-in, add the
jaasAuthenticationPlugin
element to the list of plug-ins in the broker
configuration file, as shown:
<beans>
<broker ...>
...
<plugins>
<jaasAuthenticationPlugin configuration="LDAPLogin" />
</plugins>
...
</broker>
</beans>
The configuration
attribute specifies the label of a login entry from the
login configuration file (for example, see Example 3.9). In the preceding example, the
LDAPLogin
login entry is selected.