Introduction
This document details how to configure your Openfire installation to use an
external directory such as Open LDAP or Active Directory. Integration with a
directory lets users authenticate using their directory username and password.
Optionally, you can configure Openfire to load user profile and group
information from the directory. Any group in Openfire can be designated as a
shared group, which means that you can pre-populate user‘s rosters using
directory groups.
Background
LDAP (Lightweight Directory Access Protocol) has emerged as a dominant
standard for user authentication and for storage of user profile data. It serves
as a powerful tool for large organizations (or those organizations integrating
many applications) to simplify user management issues. Many LDAP servers are
available, such as Open
LDAP, Active
Directory, and Novell‘s eDirectory.
By default, Openfire stores all user data in its database and performs
authentication using database lookups. The LDAP module replaces that
functionality and allows Openfire to:
- Use a LDAP server to authenticate a user‘s identity.
- Load user profile information from a LDAP directory.
- Load group information from an LDAP directory.
Note: Openfire treats the LDAP directory as read-only.
This document will guide you through configuring LDAP support in Openfire.
These instructions assume that you‘re a competent LDAP user, and that you‘re
familiar with Openfire setup issues.
Configuration
The Openfire setup tool includes an easy to use LDAP setup wizard. Choose the
LDAP option on the Profile Settings page to configure directory integration. The
wizard along with in-line help will guide you through the rest of the
process. Specific
tips for working with Active Directory are noted below.
If you have already completed
the setup process but need to enable LDAP integration, you can re-run the setup
tool. To do so:
- Stop Openfire.
- Edit conf/openfire.xml in your Openfire installation
folder and set <setup>true</setup> to
<setup>false</setup>.
- Restart Openfire and enter the setup tool.
Working with Active Directory
Microsoft‘s Active Directory is a broadly deployed directory system that
supports the LDAP protocol. You‘ll be prompted for several LDAP fields when
connecting to Active Directory servers, some of which are detailed below:
- Base DN
The base DN describes where to load users and groups. If you‘re using a
default Active Directory setup, all user accounts and groups are located in
the "Users" folder under your domain. In LDAP form,
that‘s cn=Users;dc=<Your Domain>. To get more specific,
say your domain is activedirectory.jivesoftware.com. In that
case, your base DN would
becn=Users;dc=activedirectory,dc=jivesoftware,dc=com. If you‘ve
customized where users are stored, you‘ll just need to replicate that folder
structure using LDAP syntax.
- Administrator DN
By default, Active Directory does not allow anonymous LDAP connections.
Therefore, you‘ll need to enter the DN of a user that‘s allowed to connect to
the server and read all user and group data. Unless you‘ve created a special
user account for this purpose, an easy choice is to use the built-in
administrator account. By default, the administrator DN is in the
formcn=Administrator,dc=<Your Domain>. Using our previous
example, cn=Administrator,cn=users,dc=activedirectory,dc=jivesoftware,dc=com.
Manually Editing the Config File
If you prefer to edit the configuration file to enable LDAP integration
directly, use the following instructions. Open the configuration
file conf/openfire.xml from your Openfire installation in
your favorite editor and add or change the following settings. Properties
flagged with ( *) must be
set. Properties flagged with (**) must be set in order to enable
LDAP group support, all other properties are optional:
Main
Settings
- provider.user.className * -- set the value to
"org.jivesoftware.openfire.ldap.LdapUserProvider".
- provider.auth.className * -- set the value to
"org.jivesoftware.openfire.ldap.LdapAuthProvider".
- ldap.host * -- LDAP server host; e.g.
localhost or machine.example.com, etc. It is possible to use many LDAP
servers but all of them should share the same
configuration (e.g. SSL, baseDN, admin account, etc). To
specify many LDAP servers use the comma or the white space character as
delimiter.
- ldap.port -- LDAP server port number. If this property is not set, the
default value is 389.
- ldap.connectionTimeout -- The value of this property is the string
representation of an integer representing the connection timeout in
milliseconds. If the LDAP provider doesn‘t connect within the specified
period, it aborts the connection attempt. The integer should be greater than
zero. An integer less than or equal to zero means no connection timeout is
specified in which case the default 10 seconds timeout is
used. Does not apply to SSL connections.
- ldap.readTimeout -- The value of this property is the string
representation of an integer representing the read timeout in milliseconds
for LDAP operations. If the LDAP provider doesn‘t get an LDAP response
within the specified period, it aborts the read attempt. The integer should
be greater than zero. An integer less than or equal to zero means no read
timeout is specified which is equivalent to waiting for the response
infinitely until it is received which defaults to the original
behavior. Requires Java 1.6 or later.
- ldap.baseDN * -- the starting DN that
searches for users will performed with. The entire subtree under the base DN
will be searched for user accounts.
- ldap.alternateBaseDN -- a second DN in the directory can optionally be
set. If set, the alternate base DN will be used for authentication, loading
single users and displaying a list of users. Content in the base DN and the
alternate DN will be treated as one.
- ldap.adminDN -- a directory administrator‘s DN. All directory operations
will be performed with this account. The admin must be able to perform
searches and load user records. The user does not need to be able to make
changes to the directory, as Openfire treats the directory as read-only. If
this property is not set, an anonymous login to the server will be
attempted.
- ldap.adminPassword -- the password for the directory administrator.
- ldap.usernameField -- the field name that the username lookups will be
performed on. If this property is not set, the default value
is uid. Active Directory users should try the default
valuesAMAccountName.
- ldap.nameField -- the field name that holds the user‘s name. If this
property is not set, the default value is cn. Active Directory
users should use the default value displayName.
- ldap.emailField -- the field name that holds the user‘s email address.
If this property is not set, the default value is mail. Active
Directory users should use the the default value mail.
- ldap.searchFields -- the LDAP fields that will be used for user
searches. If this property is not set, the username, name, and email fields
will be searched. An example value for this field is
"Username/uid,Name/cname". That searches the uid and cname fields in the
directory and labels them as "Username" and "Name" in the search UI. You can
add as many fields as you‘d like using comma-delimited "DisplayName/Field"
pairs. You should ensure that any fields used for searching are properly
indexed so that searches return quickly.
- ldap.searchFilter -- an optional search filter to append to the default
filter when loading users. The default search filter is created using the
attribute specified by ldap.usernameField. For example, if the username
field is "uid", then the default search filter would be "(uid={0})" where
{0} is dynamically replaced with the username being searched
for.
The most common usage of a search filter is to limit the
entries that are users based on objectClass. For example, a reasonable
search filter for a default Active Directory installation is
"(objectClass=organizationalPerson)". When combined with the default filter,
the actual search executed would be
"(&(sAMAccountName={0})(objectClass=organizationalPerson))".
- ldap.subTreeSearch -- by default, Openfire will search the entire LDAP
sub-tree (starting at the base DN) when trying to load users. If this
property is set to false, then sub-tree searching is disabled
and users will only be loaded directly from the base DN. Disabling sub-tree
can improve performance, but it will fail to find users if your directory is
setup to use sub-folders under the base DN.
Group
Settings
- provider.group.className ** -- set the value to
"org.jivesoftware.openfire.ldap.LdapGroupProvider".
- ldap.groupNameField ** -- the field name that
the groupname lookups will be performed on. If this property is not set, the
default value is cn.
- ldap.groupMemberField -- the field name that holds the members in a
group. If this property is not set, the default value
is member.
- ldap.groupDescriptionField -- the field name that holds the description
a group. If this property is not set, the default value
is description.
- ldap.posixMode ** -- a value of "true"
means that users are stored within the group by their user name alone. A
value of "false" means that users are stored by their entire DN within the
group. If this property is not set, the default value
is false. The posix mode must be set correctly for your server
in order for group integration to work. Posix modes for common LDAP servers:
- ldap.groupSearchFilter -- an optional search filter to append to the
default filter when loading groups. The default group search filter is
created using the attribute specified by ldap.groupNameField. For example,
if the group name field is "cn", then the default group search filter would
be "(cn={0})" where {0} is dynamically replaced with the group name being
searched for.
The most common usage of a search filter is to
limit the entries that are groups based on objectClass. For example, a
reasonable search filter for a default Active Directory installation is
"(objectClass=group)". When combined with the default filter, the actual
search executed would be
"(&(cn={0})(objectClass=group))".
Connection
Settings
- ldap.debugEnabled -- a value of "true" if debugging should be turned on.
When on, trace information about buffers sent and received by the LDAP
provider is written to System.out
- ldap.sslEnabled -- a value of "true" to enable SSL connections to your
LDAP server. If you enable SSL connections, the LDAP server port number most
likely should be changed to 636.
- ldap.initialContextFactory -- the name of the class that should be used as
an initial context factory. if this value is not specified,
"com.sun.jndi.ldap.LdapCtxFactory" will be used instead. Most users will not
need to set this value.
- ldap.autoFollowReferrals -- a value of "true" indicates that LDAP
referrals should be automatically followed. If this property is not set or is
set to "false", the referral policy used is left up to to the provider. A
referral is an entity that is used to redirect a client‘s request to another
server. A referral contains the names and locations of other objects. It is
sent by the server to indicate that the information that the client has
requested can be found at another location (or locations), possibly at another
server or several servers.
- ldap.connectionPoolEnabled -- a value of "false" disables LDAP connection
pooling. If this property is not set, the default value is "true".
Below is a sample config file section:
<jive>
...
<ldap>
<host></host>
<port>389</port>
<usernameField>uid</usernameField>
<nameField>cn</nameField>
<emailField>mail</emailField>
<baseDN>ou=People;dc=example;dc=com</baseDN>
<adminDN>cn=Directory Administrator</adminDN>
<adminPassword></adminPassword>
</ldap>
<provider>
<user>
<className>org.jivesoftware.openfire.ldap.LdapUserProvider</className>
</user>
<auth>
<className>org.jivesoftware.openfire.ldap.LdapAuthProvider</className>
</auth>
<group>
<className>org.jivesoftware.openfire.ldap.LdapGroupProvider</className>
</group>
</provider>
...
</jive>
You‘ll most likely want to change which usernames are authorized to login to
the admin console. By default, only the user with username "admin" is allowed to
login. However, you may have different users in your LDAP directory that you‘d
like to be administrators. The list of authorized usernames is controlled via
the admin.authorizedUsernames property. For example, to let
the usersnames "joe" and "jane" login to the admin console:
<jive>
...
<admin>
...
<authorizedUsernames>joe, jane</authorizedUsernames>
</admin>
...
</jive>
Custom Search Filter
By default, Openfire will load all objects under the baseDN that have the
attribute specified by ldap.usernameField. In the case that the
username field is set to "uid", the search for all users would be "(uid=*)".
However, there are cases when this logic does not work -- for example, when a
directory contains other objects besides users but all objects share "uid" as a
unique identifier field. In that case, you may need to specify a custom search
filter using ldap.searchFilter. As an example, a search filter for
all users with a "uid" and a "cn" value of "joe" would be:
(&(uid={0})(cn=joe))
The "{0}" value in the filter above is a token that should be present in all
custom search filters. It will be dynamically replaced with "*" when loading the
list of all users or a username when loading a single user.
Some custom search filters may include reserved XML entities such as "&".
In that case, you must enter the search filter into the openfire.xml file using
CDATA:
<searchFilter><![CDATA[(&(sAMAccountName={0})(|(givenName=GEORGE)(givenName=admin)))]]></searchFilter>
Custom Inital Context Factory
Some LDAP servers or application servers may require that a different LDAP
initial context factory be used rather than the default
(com.sun.jndi.ldap.LdapCtxFactory). You can set a custom initial context factory
by adding the following to openfire.xml:
<ldap>
... other ldap settings here
<initialContextFactory>com.foo.factoryClass</initialContextFactory>
</ldap>
Connection Pooling
The default LDAP provider (Sun‘s) support pooling of connections to
the LDAP server. Connection pooling can greatly improve performance, especially
on systems with high load. Connection pooling is enabled by default, but can be
disabled by setting the Jive
property
ldap.connectionPoolEnabled to
false:
<ldap>
... other ldap settings here
<connectionPoolEnabled>false</connectionPoolEnabled>
</ldap>
You should set several Java system properties to change default pool
settings. For more information, see the following pages:
Note that if you turn on LDAP debugging, connection pooling will not be
enabled. If SSL LDAP mode is enabled, you must set a system property to enable
pooling of SSL LDAP connections.
LDAP vCard Integration
The LDAP vCard provider will expose LDAP profile information as vCard data
for XMPP clients that support the XMPP vCard extension. First, enable the
provider:
<provider>
...
<vcard>
<className>org.jivesoftware.openfire.ldap.LdapVCardProvider</className>
</vcard>
...
</provider>
Next, you must add mappings between LDAP fields and vCard fields in the
openfire.xml file. The vcard attributes are configured by adding an
attrs="attr1,attr2" attribute to the vcard elements. Arbitrary text can be used
for the element values as well as MessageFormat style placeholders for the ldap
attributes. For example, if you wanted to map the LDAP attribute displayName to
the vcard element FN, the XML snippet would be: <FN
attrs="displayName">{0}</FN>
The vCard XML must be escaped in CDATA and must also be well formed. It is
the exact XML this provider will send to a client after after stripping attr
attributes and populating the placeholders with the data retrieved from LDAP.
This system should be flexible enough to handle any client‘s vCard format. An
example mapping follows.
<ldap>
<vcard-mapping>
<![CDATA[
<vCard xmlns=‘vcard-temp‘>
<FN>{displayName}</FN>
<NICKNAME>{uid}</NICKNAME>
<BDAY>{dob}</BDAY>
<ADR>
<HOME/>
<EXTADR>Ste 500</EXTADR>
<STREET>317 SW Alder St</STREET>
<LOCALITY>Portland</LOCALITY>
<REGION>Oregon</REGION>
<PCODE>97204</PCODE>
<CTRY>USA</CTRY>
</ADR>
<TEL>
<HOME/>
<VOICE/>
<NUMBER>{telephoneNumber}</NUMBER>
</TEL>
<EMAIL>
<HOME/>
<INTERNET/>
<PREF/>
<USERID>{mail}</USERID>
</EMAIL>
<TITLE>{title}</TITLE>
<ROLE></ROLE>
<ORG>
<ORGNAME>{o}</ORGNAME>
<ORGUNIT></ORGUNIT>
</ORG>
<URL>{labeledURI}</URL>
<DESC>uid: {uidNumber} home: {homeDirectory} shell: {loginShell}</DESC>
</vCard>
]]>
</vcard-mapping>
</ldap>
LDAP FAQ
Can I create new users through Openfire when using LDAP?
No, Openfire treats LDAP directories as read-only. Therefore, it‘s not
possible to create or edit users through the application.
Why is the
list of usernames not sorted in the admin console when using LDAP?
Several popular LDAP servers such as OpenLDAP do not support server-side
sorting of search results. On those servers, users will appear out of order.
However, you can enable client-side sorting of search results by
setting
ldap.clientSideSorting
to true in the XML configuration file.
I switched to LDAP
and now cannot login to the admin console. What happened?
If you can no longer login to the admin console after switching, one of
two things most likely happened:
- By default, only the username "admin" is allowed to login to the admin
console. Your directory may not contain a user with a username of "admin".
In that case, you should modify the list of usernames authorized to login
to the admin console (see above).
- You may have set the baseDN to an incorrect value. The LDAP module
recursively searches for users under the node in the directory specified
by the baseDN. When the baseDN is incorrect, no users will be found.
You can also enable debugging to get more information from the LDAP
module. To do this, add
<log><debug><enabled>true</enabled></debug></log>
to your
conf/openfire.xml
file. Log statements will be written to the
logs/debug.log