Joachim Breitner: Protecting static content selectively by OpenID

So I needed to find some protection. These were my requirements:
- I only want to protect parts of the site, as there are some pictures that I intentionally share with the public. This selection should be possible down to the individual image.
- The solution should work without any dynamic server component besides the web server itself. This rules out any self-written CGI scripts as well.
- One password, given to all my friends etc., is not sufficient as it might leak to unintended audience.
- I do not want my visitors to have to register and remember yet another username and password just for my site. I also do not want to manage this user database.
- I do not want to have do large changes to the file structure of my photo album.
.: drwxr-xr-x 2 root root 4096 2. Aug 12:03 images lrwxrwxrwx 1 root root 18 1. Aug 12:05 index.html -> private/index.html lrwxrwxrwx 1 root root 18 1. Aug 12:05 login.html -> private/login.html drwxr-xr-x 3 root root 4096 2. Aug 12:03 private ./images: lrwxrwxrwx 1 root root 33 2. Aug 12:00 pleaselogin.png -> ../private/images/pleaselogin.png lrwxrwxrwx 1 root root 28 2. Aug 12:03 public.png -> ../private/images/public.png ./private: drwxr-xr-x 2 root root 4096 2. Aug 12:00 images -rw-r--r-- 1 root root 267 2. Aug 12:03 index.html -rw-r--r-- 1 root root 94 2. Aug 12:01 loggedin.html -rw-r--r-- 1 root root 2091 2. Aug 12:03 login.html -rw-r--r-- 1 root root 10 18. Nov 2009 protected.html ./private/images: -rw-r--r-- 1 root root 4074 2. Aug 11:58 pleaselogin.png -rw-r--r-- 1 root root 2670 2. Aug 11:58 private.png -rw-r--r-- 1 root root 2043 2. Aug 11:58 public.pngAs you can see, real files only reside in private/, outside of that, only symbolic links exist. The apache configuration protects the private directory and blends it into the main directory:
<directory /var/www/nomeata.de/openid-test> RewriteEngine On # Abuse the login page as an error image RewriteCond % QUERY_STRING \.(png jpg) RewriteRule ^login.html$ /openid-test/images/pleaselogin.png # Ship private files, if they exist, unless public files exist RewriteCond $1 !^private RewriteCond /var/www/nomeata.de/openid-test/$1 !-f RewriteCond /var/www/nomeata.de/openid-test/private/$1 -f RewriteRule ^(.+)$ /openid-test/private/$1 </directory> <directory /var/www/nomeata.de/openid-test/private> AuthOpenIDEnabled On AuthOpenIDDBLocation /var/lib/apache2/mod_auth_openid/mod_auth_openid.db AuthOpenIDLoginPage /openid-test/login.html AuthOpenIDTrustRoot http://nomeata.de AuthOpenIDCookiePath / AuthOpenIDCookieLifespan 2592000 </directory>A special trick handles the login page for protected images: If the login page is requested and the referrer indicates that the user tried to access a .png or .jpg file, apache will instead ship an image containing an error message. For my photo album I have a small Perl script that, given a directory with a private/ directory therein and a list of rules in form of glob patterns, will symlink matching files and remove symlinks that are not allowed any more.
What s next? As you can see, this does not actually protect the content. It only requires the user to authenticate, then everything is visible. To select which OpenIDs are allowed to access which code, some bugs will have to be fixed in mod_auth_openid first. There was little activity there recently, I hope that the project is not dead.