JBoss.org Community Documentation
The LdapLoginModule
is a LoginModule
implementation that authenticates against an LDAP server. You would use the LdapLoginModule
if your username and credentials are stored in an LDAP server that is accessible using a JNDI LDAP provider.
The LDAP connectivity information is provided as configuration options that are passed through to the environment object used to create JNDI initial context. The standard LDAP JNDI properties used include the following:
java.naming.factory.initial
: The classname of the InitialContextFactory
implementation. This defaults to the Sun LDAP provider implementation com.sun.jndi.ldap.LdapCtxFactory
.
java.naming.provider.url : The LDAP URL for the LDAP server
java.naming.security.authentication
: The security level to use. This defaults to simple
.
java.naming.security.protocol : The transport protocol to use for secure access, such as, SSL.
java.naming.security.principal : The principal for authenticating the caller to the service. This is built from other properties as described below.
java.naming.security.credentials : The value of the property depends on the authentication scheme. For example, it could be a hashed password, clear-text password, key, certificate, and so on.
The supported login module configuration options include the following:
principalDNPrefix
: A prefix to add to the username to form the user distinguished name. See principalDNSuffix
for more info.
principalDNSuffix
: A suffix to add to the username when forming the user distinguished name. This is useful if you prompt a user for a username and you don't want the user to have to enter the fully distinguished name. Using this property and principalDNSuffix
the userDN
will be formed as principalDNPrefix + username + principalDNSuffix
useObjectCredential
: A true/false value that indicates that the credential should be obtained as an opaque Object
using the org.jboss.security.auth.callback.ObjectCallback
type of Callback
rather than as a char[]
password using a JAAS PasswordCallback
. This allows for passing non-char[]
credential information to the LDAP server.
rolesCtxDN : The fixed distinguished name to the context to search for user roles.
userRolesCtxDNAttributeName
: The name of an attribute in the user object that contains the distinguished name to the context to search for user roles. This differs from rolesCtxDN
in that the context to search for a user's roles can be unique for each user.
roleAttributeID
: The name of the attribute that contains the user roles. If not specified this defaults to roles
.
roleAttributeIsDN
: A flag indicating whether the roleAttributeID
contains the fully distinguished name of a role object, or the role name. If false, the role name is taken from the value of roleAttributeID
. If true, the role attribute represents the distinguished name of a role object. The role name is taken from the value of the roleNameAttributeId
attribute of the context name by the distinguished name. In certain directory schemas (e.g., MS ActiveDirectory), role attributes in the user object are stored as DNs to role objects instead of as simple names, in which case, this property should be set to true. The default is false.
roleNameAttributeID
: The name of the attribute of the context pointed to by the roleCtxDN
distinguished name value which contains the role name. If the roleAttributeIsDN
property is set to true, this property is used to find the role object's name attribute. The default is group
.
uidAttributeID
: The name of the attribute in the object containing the user roles that corresponds to the userid. This is used to locate the user roles. If not specified this defaults to uid
.
matchOnUserDN
: A true/false flag indicating if the search for user roles should match on the user's fully distinguished name. If false, just the username is used as the match value against the uidAttributeName
attribute. If true, the full userDN
is used as the match value.
unauthenticatedIdentity
: The principal name that should be assigned to requests that contain no authentication information. This behavior is inherited from the UsernamePasswordLoginModule
superclass.
allowEmptyPasswords : A flag indicating if empty (length 0) passwords should be passed to the LDAP server. An empty password is treated as an anonymous login by some LDAP servers and this may not be a desirable feature. Set this to false to reject empty passwords or true to have the LDAP server validate the empty password. The default is true.
The authentication of a user is performed by connecting to the LDAP server based on the login module configuration options. Connecting to the LDAP server is done by creating an InitialLdapContext
with an environment composed of the LDAP JNDI properties described previously in this section. The Context.SECURITY_PRINCIPAL
is set to the distinguished name of the user as obtained by the callback handler in combination with the principalDNPrefix
and principalDNSuffix
option values, and the Context.SECURITY_CREDENTIALS
property is either set to the String
password or the Object
credential depending on the useObjectCredential
option.
Once authentication has succeeded by virtue of being able to create an InitialLdapContext
instance, the user's roles are queried by performing a search on the rolesCtxDN
location with search attributes set to the roleAttributeName
and uidAttributeName
option values. The roles names are obtaining by invoking the toString
method on the role attributes in the search result set.
The following is a sample login-config.xml
entry.
<application-policy name="testLDAP"> <authentication> <login-module code="org.jboss.security.auth.spi.LdapLoginModule" flag="required"> <module-option name="java.naming.factory.initial"> com.sun.jndi.ldap.LdapCtxFactory </module-option> <module-option name="java.naming.provider.url"> ldap://ldaphost.jboss.org:1389/ </module-option> <module-option name="java.naming.security.authentication"> simple </module-option> <module-option name="principalDNPrefix">uid=</module-option> <module-option name="principalDNSuffix"> ,ou=People,dc=jboss,dc=org </module-option> <module-option name="rolesCtxDN"> ou=Roles,dc=jboss,dc=org </module-option> <module-option name="uidAttributeID">member</module-option> <module-option name="matchOnUserDN">true</module-option> <module-option name="roleAttributeID">cn</module-option> <module-option name="roleAttributeIsDN">false </module-option> </login-module> </authentication> </application-policy>
An LDIF file representing the structure of the directory this data operates against is shown below.
dn: dc=jboss,dc=org objectclass: top objectclass: dcObject objectclass: organization dc: jboss o: JBoss dn: ou=People,dc=jboss,dc=org objectclass: top objectclass: organizationalUnit ou: People dn: uid=jduke,ou=People,dc=jboss,dc=org objectclass: top objectclass: uidObject objectclass: person uid: jduke cn: Java Duke sn: Duke userPassword: theduke dn: ou=Roles,dc=jboss,dc=org objectclass: top objectclass: organizationalUnit ou: Roles dn: cn=JBossAdmin,ou=Roles,dc=jboss,dc=org objectclass: top objectclass: groupOfNames cn: JBossAdmin member: uid=jduke,ou=People,dc=jboss,dc=org description: the JBossAdmin group
Looking back at the testLDAP
login module configuration, the java.naming.factory.initial
, java.naming.factory.url
and java.naming.security
options indicate the Sun LDAP JNDI provider implementation will be used, the LDAP server is located on host ldaphost.jboss.org
on port 1389, and that the LDAP simple authentication method will be use to connect to the LDAP server.
The login module attempts to connect to the LDAP server using a DN representing the user it is trying to authenticate. This DN is constructed from the principalDNPrefix
, passed in, the username of the user and the principalDNSuffix
as described above. In this example, the username jduke
would map to uid=jduke,ou=People,dc=jboss,dc=org
. We've assumed the LDAP server authenticates users using the userPassword
attribute of the user's entry (theduke
in this example). This is the way most LDAP servers work, however, if your LDAP server handles authentication differently you will need to set the authentication credentials in a way that makes sense for your server.
Once authentication succeeds, the roles on which authorization will be based are retrieved by performing a subtree search of the rolesCtxDN
for entries whose uidAttributeID
match the user. If matchOnUserDN
is true the search will be based on the full DN of the user. Otherwise the search will be based on the actual user name entered. In this example, the search is under ou=Roles,dc=jboss,dc=org
for any entries that have a member
attribute equal to uid=jduke,ou=People,dc=jboss,dc=org
. The search would locate cn=JBossAdmin
under the roles entry.
The search returns the attribute specified in the roleAttributeID
option. In this example, the attribute is cn
. The value returned would be JBossAdmin
, so the jduke user is assigned to the JBossAdmin
role.
It's often the case that a local LDAP server provides identity and authentication services but is unable to use the authorization services. This is because application roles don't always map well onto LDAP groups, and LDAP administrators are often hesitant to allow external application-specific data in central LDAP servers. For this reason, the LDAP authentication module is often paired with another login module, such as the database login module, that can provide roles more suitable to the application being developed.
This login module also supports unauthenticated identity and password stacking.