mod_auth_pubtkt
0.14
About: mod_auth_pubtkt is a pragmatic Web Single Sign-On (SSO) solution for Apache web servers.
![]() ![]() |
A pragmatic Web Single Sign-On (SSO) solution
Since the "valid until" field in a ticket is necessarily in absolute time (UNIX timestamp), the clocks of the ticket-generating login server and the ticket-verifying web servers need to be more or less in sync. The longer the ticket lifetime, the less important this becomes. It's generally good practice to keep your servers' time synchronized (using NTP, for example).
Download the source code for the latest version of mod_auth_pubtkt here.
Decompress the downloaded archive and run the included "configure" script, specifying the path to apxs if necessary (use where apxs
to find it). The Apache version should be detected automatically (but note that the configure/make scripts haven't been tested under anything but FreeBSD and Mac OS X):
# tar xzfv mod_auth_pubtkt-0.x.tar.gz # cd mod_auth_pubtkt-0.x # ./configure # make # make install
The source tarball, which you can download in the Unix section above, also contains pre-compiled modules for Apache 2.0 and 2.2 (in the "bin" subdirectory):
Decompress the downloaded archive and copy the relevant module for the version of Apache you are using into the "modules" directory inside your Apache program directory, then follow the instructions below (which apply both to Unix and Windows machines). Make sure that you use an Apache version that is bundled with OpenSSL (even if you don't use HTTPS), as mod_auth_pubtkt needs it.
Note: Windows binaries for OpenSSL (you'll need the command-line openssl.exe to generate a key pair) can be found at http://www.slproweb.com/products/Win32OpenSSL.html.
See the section below for a discussion on whether to use DSA or RSA.
# openssl dsaparam -out dsaparam.pem 2048 # openssl gendsa -out privkey.pem dsaparam.pem # openssl dsa -in privkey.pem -out pubkey.pem -pubout
The dsaparam.pem file is not needed anymore after key generation and can safely be deleted.
# openssl genrsa -out privkey.pem 2048 # openssl rsa -in privkey.pem -out pubkey.pem -pubout
First of all, make sure that the module is loaded:
LoadModule auth_pubtkt_module libexec/apache/mod_auth_pubtkt.so AddModule mod_auth_pubtkt.c # Apache 1.3 only
Ensure that mod_authz_user is loaded/enabled as well.
Here's a simple VirtualHost configuration with mod_auth_pubtkt as a starting point; the configuration directives are explained below.
Note that the AuthType mod_auth_pubtkt statement is required!
<VirtualHost *:80> ServerName myserver.mydomain.com DocumentRoot /path/to/my/htdocs TKTAuthPublicKey /etc/apache2/tkt_pubkey.pem <Directory /path/to/my/htdocs> Order Allow,Deny Allow from all AuthType mod_auth_pubtkt TKTAuthLoginURL https://sso.mydomain.com/login TKTAuthTimeoutURL https://sso.mydomain.com/login?timeout=1 TKTAuthUnauthURL https://sso.mydomain.com/login?unauth=1 TKTAuthToken "myserver" require valid-user </Directory> </VirtualHost>
TKTAuthPublicKey
TKTAuthDigest
TKTAuthLoginURL
TKTAuthBackArgName
)TKTAuthTimeoutURL
TKTAuthLoginURL
is usedTKTAuthPostTimeoutURL
TKTAuthTimeoutURL
, but in case the request was a POSTTKTAuthTimeoutURL
is used (and if that is not set either, TKTAuthLoginURL
)TKTAuthUnauthURL
TKTAuthToken
) will be redirected toTKTAuthLoginURL
is usedTKTAuthBadIPURL
(since v0.7)
TKTAuthLoginURL
is usedTKTAuthRefreshURL
(since v0.3)
graceperiod
key in the ticket)
before the actual expiry will be redirected to. Only GET requests
are redirected; POST requests are accepted normally. The script at this
URL should check the ticket and issue a new oneTKTAuthLoginURL
is usedTKTAuthHeader
(since v0.9)
Cookie
then the format of the
value expects to be a valid cookie (subject to the TKTAuthCookieName
directive).
Any other header assumes the value is a simple URL-encoded value of the ticket.
The first header that has content is tried and any other tickets in other header(s) are ignored.
example, use Cookie first, fallback to X-My-Auth: TKTAuthHeader Cookie X-My-Auth
Cookie
TKTAuthCookieName
auth_pubtkt
TKTAuthBackArgName
back
TKTAuthRequireSSL
TKTAuthToken
TKTAuthFakeBasicAuth
(since v0.3)
TKTAuthPassthruBasicAuth
(since v0.8)
TKTAuthPassthruBasicKey
(since v0.8)
TKTAuthRequireMultifactor
(since v0.12)
TKTAuthMultifactorURL
(since v0.12)
TKTAuthLoginURL
is usedTKTAuthDebug
Authentication tickets to be processed by mod_auth_pubtkt are composed of key/value pairs, with keys and values separated by '=' and individual key/value pairs separated by semicolons (';'). The following keys are defined; mod_auth_pubtkt silently ignores unknown keys:
Here's an example of how a real (DSA) ticket looks:
uid=mkasper;cip=192.168.200.163;validuntil=1201383542;tokens=foo,bar;udata=mydata;multifactor=1; sig=MC0CFDkCxODPml+cEvAuO+o5w7jcvv/UAhUAg/Z2vSIjpRhIDhvu7UXQLuQwSCF=
The ticket string is saved URL-encoded in a domain cookie, usually named auth_pubtkt
, but this can be changed (using the TKTAuthCookieName
directive).
If you would like to use a custom header instead of a cookie (or want to use both), see the TKTAuthHeader
directive.
An example implementation of a login/ticket generating script in PHP is provided with the distribution (in the php-login
subdirectory). It uses a simple flat-file user database by default, but can easily be extended to support LDAP (e.g. using adLDAP), RADIUS and other authentication methods.
The ticket-generating (and verifying) functions are in pubtkt.inc
. They use the OpenSSL command-line binary directly, for two reasons:
For Perl users, a module and example CGI script are provided in the perl-login
subdirectory of the distribution.
If you use Ruby, there's a gem created by Matt Haynes that helps with generating tickets.
For Python users, Andrey Plotnikov has created a module for generating tickets.
For digital signatures, two public-key schemes are commonly used: RSA and DSA. This module supports both, but you need to choose one over the other. Put simply, and assuming that both offer the same security at similar key sizes, it's mostly a decision between speed and signature (ticket/cookie) length.
From a performance point of view, RSA is the clear winner, as each ticket only needs to be signed once, but usually verified many times on different servers. However, note that mod_auth_pubtkt caches tickets, so the verification only needs to be done once per server process and ticket (and not once per request).
If ticket size matters to you more than speed, then DSA is the better choice; otherwise, you're probably better off using RSA. In the end, it's mostly down to "religious" issues or what you're already using in your company.
# echo -n "uid=foobar;validuntil=123456789;tokens=;udata=" \ | openssl dgst -dss1 -sign privkey.pem \ | openssl enc -base64 -A
If TKTAuthDigest isn't being used, specify -dss1
for DSA, and -sha1
for RSA. Otherwise specify the TKTAuthDigest directive's algorithm (i.e. -sha256
for SHA256).
Strip the signature off the ticket and Base64-decode it into a temporary file:
# echo "MC0CFQC6c....=" | openssl enc -d -base64 -A > sig.bin
Pipe the ticket value through openssl to verify the signature using the public key in pubkey.pem:
# echo "uid=foobar;validuntil=123456789;tokens=;udata=" \ | openssl dgst -dss1 -verify pubkey.pem -signature sig.bin
Note that if rogue servers under your domain are a concern, the domain cookies used by mod_auth_pubtkt may pose a problem, since a rogue server can steal a legitimate user's ticket. This can be mitigated by marking the ticket cookie as "secure", so that it is only transported via HTTPS, which means that only servers with a valid SSL certificate for your domain can see the user's ticket (unless the user overrides security warnings in the browser). Also, including the client IP address in the ticket (as is recommended whenever possible) makes it harder to use a stolen ticket.
Another way to solve this would be to change the login server to check the "back" URL and, instead of issuing cookies directly, include the ticket in the redirect back to the web server with the desired resource, which can then install the ticket as a cookie under its own server name. This would require adding support for parsing tickets in GET parameters to mod_auth_pubtkt (could be backported from mod_auth_tkt). Also, the login server would need to keep a copy of the ticket stored in a cookie under its own server name so that the user only has to log in once, of course. Finally, since there would now be a cookie for each server, it would be much more difficult to properly log out (without closing the browser).