RedmineLDAP » History » Version 15

Wiebe Cazemier, 2013-07-03 12:01
Added troubleshooting info with ldapsearch

1 1 Jean-Philippe Lang
h1. LDAP Authentication
2 1 Jean-Philippe Lang
3 1 Jean-Philippe Lang
Redmine natively supports LDAP authentication using one or multiple LDAP directories.
4 1 Jean-Philippe Lang
5 1 Jean-Philippe Lang
h2. Declaring the LDAP
6 1 Jean-Philippe Lang
7 10 Etienne Massip
Go to Administration and click *LDAP authentication* in the menu.
8 5 Eric Davis
9 1 Jean-Philippe Lang
10 1 Jean-Philippe Lang
Enter the following:
11 1 Jean-Philippe Lang
12 1 Jean-Philippe Lang
* *Name*: an arbitrary name for the directory
13 1 Jean-Philippe Lang
* *Host*: the LDAP host name
14 1 Jean-Philippe Lang
* *Port*: the LDAP port (default is 389)
15 1 Jean-Philippe Lang
* *LDAPS*: check this if you want or need to use LDAPS to access the directory
16 9 T. Hauptman
* *Account*: enter a username that has read access to the LDAP , otherwise leave this field empty if your LDAP can be read anonymously (Active Directory servers generally do not allow anonymous access)
17 1 Jean-Philippe Lang
* *Password*: password for the account
18 1 Jean-Philippe Lang
* *Base DN*: the top level DN of your LDAP directory tree
19 1 Jean-Philippe Lang
* *Login attribute*: enter the name of the LDAP attribute that will be used as the Redmine username
20 1 Jean-Philippe Lang
21 2 Jean-Philippe Lang
Redmine users should now be able to authenticate using their LDAP username and password if their accounts are set to use the LDAP for authentication.
22 3 Jean-Philippe Lang
23 3 Jean-Philippe Lang
To test this, create a Redmine user with a login that matches his LDAP account, select the newly created LDAP in the *Authentication mode* drop-down list (this field is visible on the account screen only if a LDAP is declared) and leave his password empty. Try to log in into Redmine using the LDAP username and password.
24 1 Jean-Philippe Lang
25 1 Jean-Philippe Lang
h2. On the fly user creation
26 1 Jean-Philippe Lang
27 1 Jean-Philippe Lang
By checking *on-the-fly user creation*, any LDAP user will have his Redmine account automatically created the first time he logs into Redmine.
28 1 Jean-Philippe Lang
For that, you have to specify the LDAP attributes name (firstname, lastname, email) that will be used to create their Redmine accounts.
29 1 Jean-Philippe Lang
30 1 Jean-Philippe Lang
Here is an typical example using Active Directory:
31 1 Jean-Philippe Lang
32 1 Jean-Philippe Lang
33 1 Jean-Philippe Lang
Name     = My Directory
34 1 Jean-Philippe Lang
Host     =
35 1 Jean-Philippe Lang
Port     = 389
36 1 Jean-Philippe Lang
LDAPS    = no
37 7 John Dell
Account  = MyDomain\UserName (or UserName@MyDomain depending on AD server)
38 1 Jean-Philippe Lang
Password = <password>
39 1 Jean-Philippe Lang
Base DN  = CN=users,DC=host,DC=domain,DC=org
40 9 T. Hauptman
41 9 T. Hauptman
On-the-fly user creation = yes
42 9 T. Hauptman
43 9 T. Hauptman
  Login     = sAMAccountName
44 9 T. Hauptman
  Firstname = givenName
45 9 T. Hauptman
  Lastname  = sN
46 9 T. Hauptman
  Email     = mail
47 9 T. Hauptman
48 9 T. Hauptman
49 9 T. Hauptman
Here is another example for Active Directory with a compartmentalized intranet:
50 9 T. Hauptman
51 9 T. Hauptman
52 9 T. Hauptman
Name     = Just a description for the auth modes page
53 9 T. Hauptman
Host     = DepartmentName.OrganizationName.local
54 9 T. Hauptman
Port     = 389
55 9 T. Hauptman
LDAPS    = no
56 13 mouson chen
Account  = DepartmentName\UserName (or UserName@MyDomain depending on AD server or bind DN uid=Manager,cn=users,dc=MyDomain,dc=com)
57 9 T. Hauptman
Password = <password>
58 9 T. Hauptman
Base DN  = DC=DepartmentName,DC=OrganizationName,DC=local
59 1 Jean-Philippe Lang
60 1 Jean-Philippe Lang
On-the-fly user creation = yes
61 1 Jean-Philippe Lang
62 1 Jean-Philippe Lang
  Login     = sAMAccountName
63 1 Jean-Philippe Lang
  Firstname = givenName
64 1 Jean-Philippe Lang
  Lastname  = sN
65 1 Jean-Philippe Lang
  Email     = mail
66 1 Jean-Philippe Lang
67 1 Jean-Philippe Lang
68 1 Jean-Philippe Lang
Note that LDAP attribute names are *case sensitive*.
69 1 Jean-Philippe Lang
70 14 Alexander Menk
h3. Dynamic Bind Account 
71 14 Alexander Menk
72 14 Alexander Menk
The above setup would need a special account on the directory server which Redmine uses to pre-authenticate.
73 14 Alexander Menk
It is possible to use the code @$login$@ in the account field which then would be replaced by the current login.
74 14 Alexander Menk
The password can be left empty in this case.
75 14 Alexander Menk
76 14 Alexander Menk
77 14 Alexander Menk
Example Test:
78 14 Alexander Menk
79 6 Chris Rose
h3. Base DN variants
80 6 Chris Rose
81 6 Chris Rose
Although it's quite possible that the Base DN above is standard for Active Directory, the Active Directory at my employer's site does not use the Users container for standard users, so those instructions sent me down a long and painful path.  I recommend also trying just "DC=host,DC=domain,DC=org" if login fail swith the settings there.
82 14 Alexander Menk
83 6 Chris Rose
84 1 Jean-Philippe Lang
h2. Troubleshooting
85 1 Jean-Philippe Lang
86 4 Jean-Philippe Lang
If you want to use on-the-fly user creation, make sure that Redmine can fetch from your LDAP all the required information to create a valid user.
87 4 Jean-Philippe Lang
For example, on-the-fly user creation won't work if you don't have valid email adresses in your directory (you will get an 'Invalid username/password' error message when trying to log in).
88 6 Chris Rose
(This is not true with newer Redmine versions; the user creation dialog is populated with everything it can find from the LDAP server, and asks the new user to fill in the rest.)
89 4 Jean-Philippe Lang
90 4 Jean-Philippe Lang
Also, make sure you don't have any custom field marked as *required* for user accounts. These custom fields would prevent user accounts from being created on the fly.
91 6 Chris Rose
92 1 Jean-Philippe Lang
Errors in the login system are not reported with any real information in the Redmine logs, which makes troubleshooting difficult.  However, you can found most of the information you need using ??Wireshark?? between your Redmine host and the LDAP server. Note that this only works if you have permissions to read network traffic between those two hosts.
93 15 Wiebe Cazemier
94 15 Wiebe Cazemier
You can also use the tool 'ldapsearch' to test if your settings are correct. Log into the Linux machine hosting your redmine (and possibly install ldaputils) and run this:
95 15 Wiebe Cazemier
96 15 Wiebe Cazemier
    ldapsearch -x -b  "dc=example,dc=com" -H ldap://hostname/ -D "DOMAIN\USER" -w mypassword [searchterm]
97 15 Wiebe Cazemier
98 15 Wiebe Cazemier
If succesful, you will get a listing of the contents of the AD, matching your search query. Then, you will know what how to fill out the fields in the LDAP config in Redmine.
99 12 Etienne Massip
100 12 Etienne Massip
101 12 Etienne Massip
h3. ??Account?? value format
102 12 Etienne Massip
103 12 Etienne Massip
The username for the bind credentials might need to be specified as a DN(i.e. CN=user,OU=optional,DC=domain,DC=com) rather than as a UPN( or as ??domain\user??, as pointed out by this comment in source:trunk/vendor/plugins/ruby-net-ldap-0.0.4/lib/net/ldap.rb:
104 11 John Lewin
105 11 John Lewin
  # As described under #bind, most LDAP servers require that you supply a complete DN
106 11 John Lewin
  # as a binding-credential, along with an authenticator such as a password.
107 6 Chris Rose
108 8 Oli Kessler
109 8 Oli Kessler
h3. OpenDS 
110 8 Oli Kessler
111 8 Oli Kessler
If you are using the OpenDS server, you might have issues with the request control "Paged results" sent with the initial query searching for the user by the specified login attribute. This request control 1.2.840.113556.1.4.319 is not allowed for anonymous users by default, thus preventing redmine from finding the user in the directory even before the binding takes place.
112 8 Oli Kessler
113 8 Oli Kessler
Add a global ACI like this
114 8 Oli Kessler
115 8 Oli Kessler
./dsconfig -h SERVER_IP -p 4444 -D cn="Directory Manager" -w PASSWORD -n set-access-control-handler-prop --trustAll 
116 8 Oli Kessler
--add global-aci:\(targetcontrol=\"1.2.840.113556.1.4.319\"\)\ \(version\ 3.0\;\ acl\ 
117 8 Oli Kessler
\"Anonymous\ control\ access\ to\ 1.2.840.113556.1.4.319\"\;\ allow\ \(read\)\ userdn=\"ldap:///anyone\"\;\)
118 8 Oli Kessler
</pre>Note: Enter the command on one line, use the escaping exactly as indicated (the \ after "acl" is meant to be "\ " for a space).