<img height="1" width="1" style="display:none;" alt="" src="https://px.ads.linkedin.com/collect/?pid=299788&amp;fmt=gif">

Apache LDAP Auth for Atlassian

Content Management, Atlassian, Atlassian Tools, User Experience, Software Solutions

Normally we prefer to use Nginx as a reverse proxy for Atlassian apps. But when it comes to LDAP/AD authentication, Apache is the best option.  Nginx is capable of forcing web-server authentication, but it requires an unofficial plugin. (nginx-auth-ldap)
Obviously, for our enterprise clients, it's not worth the risk when Apache has an official mod for LDAP that has been around for years. It's pretty easy to find information on how to configure Apache for LDAP authentication, but what do you do when your app also has internal directory users that need to be authenticated at the same time.  I'm going detail an example config for any others who might be stuck on this and maybe haven't implemented web-server level LDAP authentication because of this.
This example is based on a Jira server that runs on a service port of 9000 and is accessed through https://jira.example.com/ but can redirect from a standard http request.

MODS to enable

The default configs for most Apache servers have all the LoadModule statements ready to go, you just have to uncomment them in the httpd.conf file and restart.

  • mod_proxy
  • mod_proxy_http
  • mod_proxy_connect
  • mod_ssl
  • mod_ldap
  • mod_authnz_ldap

Redirect to HTTPS

  • NameVirtualHost for both http scheme's (80, and 443)
  • A VirtualHost listening for 80 and 443
  • ProxyPass always points to the service account port (9000) through http.
  • Define the SSL certificate and key locations.
  • Make sure SSLEngine and SSLProxyEngine are turned on.

[xml]
NameVirtualHost *:80
NameVirtualHost *:443
<VirtualHost *:80>
ServerName jira.example.com
Redirect / https://jira.example.com/
</VirtualHost>
<VirtualHost *:443>
ServerName jira.example.com
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyRequests Off
ProxyPreserveHost On
ProxyPass / http://jira.example.com:9000/
ProxyPassReverse / http://jira.example.com:9000/
SSLCertificateFile /etc/ssl/example/wild/wildcard.cer
SSLCertificateKeyFile /etc/ssl/example/wild/example-wild.key
SSLEngine On
SSLProxyEngine On
</VirtualHost>
[/xml]

Add in the LDAP config

  • Add a <Location /> tag
  • Use AuthUserFile /dev/null if there's no need for internal directory access.
  • For the more common case, where an internal account should be accessible, use
    • AuthBasicProvider ldap file
    • AuthUserFile /path/to/.htpasswd
  • Create a directory for .htpasswd to live and use this bash statement to generate a password file.
    • htpasswd -b /var/www/auth/.htpasswd localadmin
    • You will be prompted for a password, which is then stored encrypted in the file.
  • If Jira and Apache live on the same server, Allow from 127.0.0.1, and the IP of the box.

[xml]
<Location />
# Using this to bind
AuthLDAPBindDN "CN=example,OU=example,DC=dc1,DC=dc2"
AuthLDAPBindPassword "password"
# search user
AuthLDAPURL "ldap://example.com:389/dc=dc1,dc=dc2?sAMAccountName?sub?(objectClass=*)"
AuthType Basic
AuthName "USE YOUR WINDOWS ACCOUNT"
AuthBasicProvider ldap <span style="color: #ff0000;">file</span>
# Important, otherwise "(9)Bad file descriptor: Could not open password file: (null)"
AuthUserFile /var/www/auth/.htpasswd
require valid-user
Satisfy any
Deny from all
Allow from 127.0.0.1
Allow from << server IP >>
</Location>
[/xml]

The complete Jira config

[xml]
NameVirtualHost *:80
NameVirtualHost *:443
<VirtualHost *:80>
ServerName jira.example.com
Redirect / https://jira.example.com/
</VirtualHost>
<VirtualHost *:443>
ServerName jira.example.com
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyRequests Off
ProxyPreserveHost On
ProxyPass / http://jira.example.com:9000/
ProxyPassReverse / http://jira.example.com:9000/
SSLCertificateFile /etc/ssl/example/wild/wildcard.cer
SSLCertificateKeyFile /etc/ssl/example/wild/example-wild.key
SSLEngine On
SSLProxyEngine On
<Location />
# Using this to bind
AuthLDAPBindDN "CN=example,OU=example,DC=dc1,DC=dc2"
AuthLDAPBindPassword "password"
# search user
AuthLDAPURL "ldap://example.com:389/dc=dc1,dc=dc2?sAMAccountName?sub?(objectClass=*)"
AuthType Basic
AuthName "USE YOUR WINDOWS ACCOUNT"
AuthBasicProvider ldap file
# Important, otherwise "(9)Bad file descriptor: Could not open password file: (null)"
AuthUserFile /var/www/auth/.htpasswd
require valid-user
Satisfy any
Deny from all
Allow from 127.0.0.1
Allow from << server IP >>
</Location>
</VirtualHost>
[/xml]

ARGHHH...I Can't logout!

So, "AuthType Basic" doesn't have a native method to logout and clear the authentication cache. Most browsers do a pretty good job at doing this when all windows are closed. But what if you want to switch to the local admin account to fix something real quick? What a pain it is to have to close your browser to be able to login again. I have typically 10 to 20 other tab's open for other things I'm working on at any given moment. So, this is unacceptable for most admin's.... Thanks to ddotsenko for a totally acceptable workaround found here!

  1. Create a Bookmark...something like "Apache Logout"
  2. Set the location to the JavaScript below.
  3. Click the bookmark any time you want to change your login!

[javascript]javascript:(function(c){var a,b="You should be logged out now.";try{a=document.execCommand("ClearAuthenticationCache")}catch(d){}a||((a=window.XMLHttpRequest?new window.XMLHttpRequest:window.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):void 0)?(a.open("HEAD",c||location.href,!0,"logout",(new Date).getTime().toString()),a.send(""),a=1):a=void 0);a||(b="Your browser is too old or too weird to support log out functionality. Close all windows and restart the browser.");alert(b)})(/*pass safeLocation here if you need*/);[/javascript]

TAGS: Content Management, Atlassian, Atlassian Tools, User Experience, Software Solutions

0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Subscribe to Our Newsletter

Recent Blog Posts