I have some internal web sites running on my home server. Earlier I configured WebAuth with WebKDC to create SSO-like experience. This was working well, but I wanted to use some 3rd party solution to be able to use auth on remote services even if local WebAuth host is not accessible.
The requirements were:
- Specify the list of users which are allowed to login
- Don’t require server-side scripting
Since Ubuntu SSO is already used for Launchpad, Ubuntu One and various other services I decided that it is good enough for my small network.
Ubuntu hosts are using python-apache-openid python module and it has a very nice feature of being able to restrict access to some launchpad teams. It is not yet critical for me so I decided to look around in the archive and found libapache2-mod-auth-openid
This is a packaged version of mod_auth_openid from http://findingscience.com/mod_auth_openid/ - that web site contains the documentation for the module as well as examples.
The version in Oneiric is 0.5 which did not contain the feature I was after, the ability to restrict the access to some set of OpenID users without resorting to external script. So I went forward and updated the package to 0.6 and for the first time I was so pleased with the resulting package that I decided to send the updates to Debian maintainer. The updated package was successfully built in my ppa:rye/ppa and can be installed on Oneiric with
sudo apt-add-repository ppa:rye/ppa sudo apt-get update sudo apt-get install libapache2-mod-auth-openid
apt-add-repository is available from python-software-properties package.Please verify that you have installed version 0.6:
$ apt-cache policy libapache2-mod-auth-openid libapache2-mod-auth-openid: Installed: 0.6-0ubuntu1 Candidate: 0.6-0ubuntu1
Configuration
I started with the following in my /etc/apache2/sites-available/default and marked the changed parts in bold
<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot /var/www
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /var/www/>
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
</Directory>
<Location />
AuthType OpenID
Require valid-user
AuthOpenIDTrusted ^https://login.ubuntu.com/\+openid
AuthOpenIDLoginPage /openid/
AuthOpenIDCookiePath /
</Location>
<Location /openid>
Order allow,deny
Allow from all
Satisfy any
</Location>
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
<Directory "/usr/lib/cgi-bin">
AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny
Allow from all
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/access.log combined
Alias /doc/ "/usr/share/doc/"
<Directory "/usr/share/doc/">
Options Indexes MultiViews FollowSymLinks
AllowOverride None
Order deny,allow
Deny from all
Allow from 127.0.0.0/255.0.0.0 ::1/128
</Directory>
</VirtualHost>
I am using a custom login page since I don’t need to enter my identifier every time. I am using a single provider so I am submitting an OpenID request automatically to Ubuntu SSO.
The /var/www/openid/index.html page is simple:
The query string parsing is actually needed to display the error that has been passed to the page in case the request is canceled on the provider or something else has happened.
Now the module needs to be enabled (this was not working in 0.5 out of the box) and apache needs to be restarted:
sudo a2enmod authopenid sudo service apache2 restart
Now you have OpenID enabled for your virtual host root directory. The thing is it is enabled for everybody with Ubuntu SSO account so we need to restrict the access.
To find your OpenID identifier, log into your system using OpenID and browse the logs:
192.168.1.114 - https://login.ubuntu.com/+id/hPQWPsH ↩ [12/Nov/2011:12:24:54 +0200] ↩ "GET / HTTP/1.1" 304 210 "-" "Mozilla/5.0 ↩ (Ubuntu; X11; Linux x86_64; rv:8.0)
Accounts that exist in launchpad can find out their +id/… value from the https://launchpad.net/~yournick, the openid.delegate will have this info. Launchpad login service and Ubuntu SSO service are currently using the same database, but we are targeting SSO.
<link rel="openid.delegate" href="https://login.launchpad.net/+id/hPQWPsH" />
The OpenID value needs to go to the apache config
<Location />
AuthType OpenID
Require user https://login.ubuntu.com/+id/hPQWPsH
AuthOpenIDTrusted ^https://login.ubuntu.com/\+openid
AuthOpenIDLoginPage /openid/
AuthOpenIDCookiePath /
</Location>
Restart apache, and only the user specified in the Require user directive will be able to access the resource
Limitations
This module can be used only for ID authentication. While it is technically possible to request the OpenID provider to reply with user email or any other attributes, the module does not provide any protection from changing the values as they are traveling as a GET request back to the original form target page.