mod_auth_pubtkt: a pragmatic Web Single Sign-On (SSO) solution

Slides from presentation at SwiNOG 16 (PDF)

Introduction – the Web SSO dilemma

Are you familiar with this situation? You've got a few (dozen, perhaps) web servers on your company's Intranet, and most/all of them run Apache and require HTTP authentication to access content and scripts stored on them. However, each of them has its own (most likely htpasswd-based) user database, meaning that each time a new employee starts working at your company (or an employee leaves), all the htpasswd files on the various web servers need to be changed. Also, the fact that people need to keep logging in all the time only entices them to store passwords in their browser.

If so, then chances are that you've already been looking for a (open source) web single sign-on solution. You may have found projects like Shibboleth, Pubcookie or CoSign, but none of them may have met your requirements (if one did and you're happy with it, then it's probably time to stop reading).

At the company that I work for, the requirements for a simple web single sign-on system were as follows:

My evaluations of existing open-source projects turned up the following:

mod_auth_tkt to the rescue... well, almost

mod_auth_tkt is a simple approach to Web SSO using (session) cookie-based tickets that are generated by a central server and passed to each web server participating in the SSO scheme. The format of the tickets is open, and implementation of a login/ticket-generating server is mostly left to the person deploying mod_auth_tkt. The tickets are signed with MD5 and a shared secret known to the login server and all web servers. This is the only point I didn't like about mod_auth_tkt: if just one single web server's configuration file is compromised, it's possible to generate tickets for all other web servers with the same shared secret.

The mod_auth_pubtkt solution

mod_auth_pubtkt is an Apache module that authenticates a user based on a cookie with a ticket that has been issued by a central login server and digitally signed using either RSA or DSA. This means that only the trusted login server has the private key required to generate tickets, while web servers only need the corresponding public key to verify them.

Whenever mod_auth_pubtkt encounters a request without a valid ticket/cookie, it redirects the user to a pre-configured login URL, passing the originally requested URL as a GET parameter. The login server can then prompt the user for credentials, verify them using any authentication backend it chooses, and upon success, generate a login ticket (signed with its private key), return it in a cookie to the client, and finally redirect the user back to the originally requested URL.

sequence diagram

Tickets may contain a list of "tokens", and each resource (directory etc.) can be made to require a specific token, thus giving a simple but effective form of authorization (the login server can assign different tokens to different users, e.g. based on group membership).

If the cookie is scoped to the entire domain, all web servers with mod_auth_pubtkt in the domain and configured with the same public key will accept the ticket and not require any further authentication from the client until the ticket expires.

Note that a rogue server could steal a valid ticket provided by a client (or it could be sniffed by an adversary if using plain HTTP); however, the client IP address can be included in the ticket, making it harder for other people to use.

How does mod_auth_pubtkt compare to mod_auth_tkt?

Aside from the obvious change in the signature algorithm (RSA/DSA instead of keyed MD5), the following major differences exist:

Apache versions and operating systems tested

mod_auth_pubtkt has been tested with the following Apache versions and operating systems (please send your additions to this list to mk@neon1.net):

Getting support

The Google Group mod_auth_pubtkt-users is a good place to post your questions and exchange ideas etc. with other users.

Repository

The source code for mod_auth_pubtkt is maintained in a GitHub repository.

To Do/Wishlist

License

mod_auth_pubtkt is licensed under the terms of the Apache License of the Apache Software Foundation.

Credits

mod_auth_pubtkt is based on mod_auth_tkt by Open Fusion Pty. Ltd., to whom I'm greatly indebted.

Frederic Planchon <frederic at planchon dot org> contributed improved ticket refreshing support and a workaround for an issue with PHP stripping the username from requests.

Günter Knauf <info at gknw dot de> provided a patch to remove an external header dependency.

John Wittkoski contributed a patch to add TKTAuthBadIPURL, and some other minor changes.

Assaf Gordon contributed a Perl module to generate tickets.

Ivo De Decker contributed patches to set the public key per directory, and to make the login URL optional.

Author

mod_auth_pubtkt was written by Manuel Kasper <mk@neon1.net>, with contributions from others (see above).