Apache HTTPD and LDAP attributes

More fun with Apache HTTPD. This time I wanted to access a user’s email address and user id, both stored in LDAP, in an application without LDAP integration. Thankfully, this turned out to be pretty easy. But first, some background.

The application is a very simple Java application, which sits behind HTTPD as a Reverse Proxy. The Reverse Proxy handles authentication, because reinveting the wheel gets a bit dull after a while, and mod_authnz_ldap works just fine. But while adding a feature to the application, I suddenly needed access to the user’s userid and email address, for Reasons™.

The documentation turned out to be somewhat helpful, if cryptic. There is a relatively easy way to expose LDAP attributes to CGI scripts using mod_authnz_ldap — which can set environment variables for perusal by the CGI script. Using the same mechanism in combination with a reverse proxy was a bit trickier; after all, the Java application is running in a Jetty container and it talks to the proxy using HTTP. That doesn’t really offer room for injecting environment variables.

Towards a solution

The solution requires two parts, one in the LDAP configuration, and one where an extra HTTP header is injected.

mod_authnz_ldap exposes certain LDAP attributes as environment variables. For instance, uid will be exposed as AUTHENTICATE_UID, while mail is exposed as AUTHENTICATE_MAIL. Exposinguid or mail is as simple as including them in the AuthLDAPURL string:

AuthLDAPURL "ldap://your.ldap.server/ou=foo=dc=bar?uid,mail"

The salient part in the example is ?uid,mail. This is what triggers the creation of the aforementioned environment variables.

In order to then turn those environment variables into HTTP Headers for the proxied application, we’ll have to fiddle a bit more:

RequestHeader set X-FOO-EMAIL %{AUTHENTICATE_MAIL}e
RequestHeader set X-FOO-UID %{AUTHENTICATE_UID}e

This syntax is bewilderingly ugly. This kind of thing is really where HTTPD shows its age. The trailing e indicates that the preceding name is an environment variable. The rest of the syntax is pretty obvious, at least.

And for good measure, we can unset the Authorization header after exposing these values, the application doesn’t need to know any LDAP passwords.

RequestHeader unset Authorization

All in all, a pretty easy fix, but it took a while to figure it out.

— Elric