django-openid-auth

Last week, we released the source code to django-openid-auth.  This is a small library that can add OpenID based authentication to Django applications.  It has been used for a number of internal Canonical projects, including the sprint scheduler Scott wrote for the last Ubuntu Developer Summit, so it is possible you’ve already used the code.

Rather than trying to cover all possible use cases of OpenID, it focuses on providing OpenID Relying Party support to applications using Django’s django.contrib.auth authentication system.  As such, it is usually enough to edit just two files in an existing application to enable OpenID login.

The library has a number of useful features:

  • As well as the standard method of prompting the user for an identity URL, you can configure a fixed OpenID server URL.  This is useful for deployments where OpenID is being used for single sign on, and you always want users to log in using a particular OpenID provider.  Rather than asking the user for their identity URL, they are sent directly to the provider.
  • It can be configured to automatically create accounts when new identity URLs are seen.
  • User names, full names and email addresses can be set on accounts based on data sent via the OpenID Simple Registration extension.
  • Support for Launchpad‘s Teams OpenID extension, which lets you query membership of Launchpad teams when authenticating against Launchpad’s OpenID provider.  Team memberships are mapped to Django group membership.

While the code can be used for generic OpenID login, we’ve mostly been using it for single sign on.  The hope is that it will help members of the Ubuntu and Launchpad communities reuse our authentication system in a secure fashion.

The source code can be downloaded using the following Bazaar command:

bzr branch lp:django-openid-auth

Documentation on how to integrate the library is available in the README.txt file.  The library includes some code written by Simon Willison for django-openid, and uses the same licensing terms (2 clause BSD) as that project.

11 Comments

  1. Posted 14 April, 2009 at 8:37 pm | Permalink

    Is Django used for Launchpad at all? Or is it just for other internal Canonical stuff?

  2. Posted 14 April, 2009 at 10:35 pm | Permalink

    Launchpad is not a Django application — it is built on top of Zope 3 and Storm.

    Some of the non-internal projects we’ve got using Django include summit.ubuntu.com and paste.ubuntu.com.

  3. Posted 14 April, 2009 at 11:10 pm | Permalink

    Would this also work with Google App Engine?

  4. Posted 14 April, 2009 at 11:47 pm | Permalink

    Marius: I don’t think there is any code in django-openid-auth that would be a problem. However, it is built on top of Jan Rain’s python-openid which is more likely to have compatibility problems.

    At a minimum, you might need to provide a custom URLFetcher class that uses the appengine HTTP API. It is possible that someone has already done this work though, so you might want to google it.

  5. Ivan
    Posted 15 April, 2009 at 3:18 pm | Permalink

    Hi,

    I was looking for an OpenID library to use in our Django application but when I run “python manage.py syncdb” I receive the following error. Am I missing something?

    Creating table django_openid_auth_useropenid

    _mysql_exceptions.OperationalError: (1170, “BLOB/TEXT column ‘claimed_id’ used in key specification without a key length”)

  6. Posted 15 April, 2009 at 3:27 pm | Permalink

    Looks like the known issues in the googleappengine relating to python-openid have been fixed in the last few months (i.e. issue #404). So it should work!

  7. Posted 15 April, 2009 at 5:47 pm | Permalink

    Ivan: I can’t say I tested it on MySQL: the test suite is against SQLite, and the only other database we use it against is PostgreSQL.

    You could try editing django_openid_auth/models.py and changing the claimed_id definition to a CharField with a shorter maximum length. If that works for you, please file a bug report in Launchpad.

  8. Posted 19 April, 2009 at 1:20 pm | Permalink

    @Ivan: It’s Django’s fault actually. You need to open django_openid_auth/models.py file and remove unique=True from the claim_id which is in the UserOpenID class, then sync. After that you need ALTER TABLE to create the proper index, then add unique=True option again in the file. Hope this helps.

    Cheers,
    Faruk

  9. Aaron
    Posted 27 April, 2009 at 8:55 am | Permalink

    Thanks for the great app. I and was unclear what the best way is to deal with user information like a username, email address, etc for an openid user. Should I just follow http://docs.djangoproject.com/en/dev/topics/auth/#storing-additional-information-about-users and add a profile model? If so, should that model be foreignkeyed to django_openid_auth.openiduser?

    Also, is there a way to get extended information like a username from the openid provider?

  10. Posted 28 April, 2009 at 6:09 pm | Permalink

    Faruk: that column should indeed be unique — each identity URL must only be associated with a single user. As I mentioned above, the column should probably be changed to CharField with an appropriate length for MySQL compatibility.

    Aaron: django-openid-auth already supports querying the openid provider for a full name, nickname and email address using the simple registration extension. It uses these when creating new django.contrib.auth User objects. As there is already space in the User object to store them, it doesn’t use a profile model.

  11. Posted 10 May, 2009 at 5:59 pm | Permalink

    Has anyone gotten this to work with App Engine and Django 1.0? I’d love to use it for my project but I’m getting the following error:
    ViewDoesNotExist: Could not import django_openid_auth.views. Error was: No module named contenttypes.models

    This is peculiar because I don’t see any reference to contenttypes except in settings.py. I’m using google-app-engine-django and contenttypes is commented out, though uncommenting it doesn’t help (you can see my whole process here: http://www.bubblefoundry.com/blog/2009/05/installing-the-google-app-engine-sdk-and-django-102/). As you can tell, I’m quite new to Django and App Engine, so any help would be appreciated.

    Peter