When integrating Redmine with Active Directory via LDAP, the authentication sequence follows this pattern:
1. User enters credentials in Redmine login form
2. Redmine binds to AD using your configured service account (or anonymously)
3. System searches for the user under specified Base DN
4. If found, attempts to bind with user's DN and provided password
5. On success, creates/updates user record in Redmine
From your setup, these elements need verification:
Host: ims.example.com
Port: 389
Base DN: cn=Users,dc=ims,dc=example,dc=com
Login attribute: sAMAccountName
Account suffix: @ims.example.com (often required)
Based on your symptoms, try these solutions:
1. Authentication Method
Add this to your Redmine LDAP config:
Authentication method: Simple TLS (or STARTTLS if required)
Account: IMS\\me (or me@ims.example.com)
Verify the account has proper bind permissions
2. User Login Format
Test these login formats systematically:
Format 1: me (pure sAMAccountName)
Format 2: me@ims.example.com (UPN format)
Format 3: IMS\\me (legacy domain format)
Use this Ruby code snippet to test LDAP connectivity directly:
require 'net/ldap'
ldap = Net::LDAP.new(
host: 'ims.example.com',
port: 389,
auth: {
method: :simple,
username: "CN=me,CN=Users,DC=ims,DC=example,DC=com",
password: "your_password"
}
)
if ldap.bind
puts "Authentication successful!"
else
puts "Error: #{ldap.get_operation_result.message}"
end
Add these to config/configuration.yml:
ldap:
servers:
ims_ad:
host: ims.example.com
port: 389
attribute: sAMAccountName
base: CN=Users,DC=ims,DC=example,DC=com
admin_user: CN=ServiceAccount,OU=ServiceAccounts,DC=ims,DC=example,DC=com
admin_password: "service_account_password"
Before going live:
1. Test with a fresh test user in AD
2. Verify TLS certificate if using encryption
3. Check Redmine logs (log/production.log)
4. Confirm no firewall blocks port 389
When integrating Redmine with Active Directory, several critical components must align perfectly. From your description, you've got the basic LDAP connection working (as evidenced by the successful test), but the authentication flow is failing. Let's break this down systematically.
# Minimal working LDAP auth settings for AD
host: ims.example.com
port: 389
base_dn: cn=Users,dc=ims,dc=example,dc=com
account: IMS\\me@example.com # or me@example.com
account_password: "your_AD_password"
attr_login: sAMAccountName
attr_firstname: givenName
attr_lastname: sn
attr_mail: mail
Active Directory can accept multiple username formats, but Redmine needs precise configuration. The most reliable formats are:
- User Principal Name (UPN): me@example.com
- Down-Level Logon Name: IMS\me
- sAMAccountName: me (your current setting)
Try modifying your login attempts to use the UPN format first, as it's the most consistent across AD configurations.
Your configuration is missing a critical component - the account DN that Redmine should use to bind to AD before searching for users. Add this to your LDAP config:
account: IMS\\me@example.com # or cn=me,cn=Users,dc=ims,dc=example,dc=com
account_password: "your_AD_password"
Here's a systematic approach to diagnose your issue:
- Verify LDAP search works:
ldapsearch -x -H ldap://ims.example.com:389 \ -D "cn=me,cn=Users,dc=ims,dc=example,dc=com" \ -W -b "cn=Users,dc=ims,dc=example,dc=com" \ "(sAMAccountName=me)"
- Check Redmine logs:
tail -f /var/log/redmine/production.log # Look for LDAP-related errors during login attempts
- Test with simple credentials:
Temporarily create a test AD user with minimal permissions to isolate permission issues.
If basic binding isn't working, you might need these additional parameters:
# In config/configuration.yml
ldap_uses_tls: true # If using LDAPS
ldap_tls_verify: none # For self-signed certs
ldap_filter: "(memberOf=CN=RedmineUsers,OU=Groups,DC=ims,DC=example,DC=com)"
Based on numerous AD integrations, these are frequent issues:
- Clock skew: Ensure your Redmine server's time is synchronized with AD (Kerberos is time-sensitive)
- Password policies: AD might block simple bind attempts if password is expired
- Special characters: Escape backslashes properly in configuration files
- Firewall rules: Verify port 389 (or 636 for LDAPS) is open between servers
Here's a complete working example for your scenario:
# In Redmine LDAP settings
Name: AD Auth
Host: ims.example.com
Port: 389
Base DN: cn=Users,dc=ims,dc=example,dc=com
LDAP filter: (objectCategory=user)
On-the-fly creation: Yes
Login attribute: sAMAccountName
Admin account: me@example.com
Admin password: [your_password]
Attributes mapping:
First name: givenName
Last name: sn
Email: mail