Getting to the backends

Posted on 08/02/

As I already exposed, simple web apps will be using mod_auth_tkt pretty fast if they where counting on http basic authentication.

When you control the software being used (be it yours or open source) you can always take on parsing the ticket to get the info back, be it in a cookie, be it in a parameter via GET.

Let's examine a more complex scenario. Problems start ariving when using application servers, or proxying to non auth_tkt aware servers or applications. The frontend can validate the ticket, (authenticating the user), but, since mod_auth_tkt basically leaves the ticket in the REMOTE_USER environment variable, and these variables don't get proxied, you don't recieve the logged in user in the backend. So... lets try to find some ways of getting the info to the backends (thanks to the people on the mod_auth_tkt list for the pointers).

Using headers

Put the REMOTE_USER in an HTTP header. Use mod_headers.

ProxyPass /headertest/ http://backend/xxx/
ProxyPassReverse /headertest/ http://backend/xxx/

<Location /headertest/>
   AuthType Basic
   TKTAuthLoginURL /login
   TKTAuthTimeout 600s
   RequestHeader set X-AuthTkt-Remote-User "%{REMOTE_USER}e"
   RequestHeader set X-AuthTkt-Data        "%{REMOTE_USER_DATA}e"
   RequestHeader set X-AuthTkt-Tokens      "%{REMOTE_USER_TOKENS}e"
   require valid-user
</Location>

And in the backend, just pickup the results! (If you are running a CGI on the backend, just loookup the environment variable: HTTP_X_AUTHTKT_REMOTE_USER, HTTP_X_AUTHTKT_TOKENS, HTTP_X_AUTHTKT_DATA. Of course, you'll say! I have to modify the backend software to read from the HTTP_X_AUTHTKT_REMOTE_USER. If the backend server is another Apache, you still have an Ace up your sleeve mod_setenvif.

    SetEnvIf X-AuthTkt-Remote-User "(.*)" REMOTE_USER=$1
    SetEnvIf X-AuthTkt-Data        "(.*)" REMOTE_USER_DATA=$1
    SetEnvIf X-AuthTkt-Tokens      "(.*)" REMOTE_USER_TOKENS=$1

Using URL GET parameters

You can rewrite the REMOTE_USER to a parameter in the URL. mod_rewrite can handle this with it's eyes closed, and fetch that in the backend.

ProxyPass /headertest/ http://backend/xxx/
ProxyPassReverse /headertest/ http://backend/xxx/

<Location /headertest/>
   AuthType Basic
   TKTAuthLoginURL /login
   TKTAuthTimeout 600s

   RewriteEngine on
   RewriteRule  ^(.+)\??(.*)$   $1?remote_user=%{ENV:REMOTE_USER}$2    [QSA]

   require valid-user
</Location>

mod_rewrite can set environment variables too, so, if you do the inverse process (set the value of the GET parameter to the environment variable), you get the same result. I like the header solution best because mod_rewrite is a heavy module, and just adds the module that the frontend needs, and the one that the backend needs.

There was a comment on the list on getting username and password to the backends (for apps that need the two on every request), but for that you have to store the password encripted in the cookie. I'll have a shot at that one in another post (and maybe use the tecnique in the real world in an OS application... we'll see).