Crowd Authentication for Google’s AppEngine

The launch of Google’s AppEngine has given me the obligation to find out what it’s all about, and the opportunity to learn a bit more about one of our products, Crowd — and, of course, pick up some Python along the way.

I began by working through Google’s Guestbook example, and then replaced its use of Google’s Users API with single sign on via Crowd.

Crowd Single Sign On

A Crowd client application authenticates via SOAP calls to a Crowd server. The sequence looks like this:

Crowd authentication sequence diagram

Duck Punching httplib for SOAP

I used the soaplib Python SOAP library to talk to Crowd. This library uses httplib to talk to the SOAP server, which is a problem as AppEngine only allows applications to use Google’s HTTP request mechanism.

I adapted soaplib to use Google’s fetch function by ‘Duck Punching’, also known as ‘Monkey Patching’. This globally overrides a library class with a class of your own:

import httplib

class AppEngineHTTPConnection(object):
... delegate the functions called by soaplib to Google's fetch ...

class Crowd(object):
def __init__(self, path, applicationName, applicationPassword):
    # do some monkeypatching
    httplib.HTTPConnection = AppEngineHTTPConnection

Simple, and safe in this case, as we want any client of httplib to use our replacement.

By default, soaplib puts an empty namespace on strings and arrays, so I cut, pasted and renamed these classes, changing them to explicitly set the correct namespace. A Pythonista could probably duck-punch their way out of that with less duplication

My modified Guestbook application adds login and logout URLs which authenticate with Crowd and create the appropriate cookie.

Caveats and Conclusions

AppEngine doesn’t support SSL, so your username and password are transmitted unencrypted to the application. To avoid this you could write a small authentication application to be hosted with your Crowd server under SSL.

Your Crowd server and your Google AppEngine application need to be on the same domain, in order to share the Crowd SSO cookie. This should be possible by assigning your domain to a Google Apps account, but I haven’t managed to add my Google Apps domain to my Google AppEngine application yet.

Python

I strongly dislike weakly typed languages such as Python. IDEs can’t sensibly provide code completion, and I found that I made many errors which were only caught at runtime. Most of these were in code which could easily have been type checked at compile time.

The sooner type inference is added to Python or AppEngine supports JVM languages, the happier I’ll be. I expect the latter to happen first.

Code

The code for this AppEngine app can be found in my crowd-appengine Git repository. As usual, get a snapshot if you don’t have a git client installed.

2 Comments

  1. Posted May 3, 2008 at 5:21 am | Permalink

    When I started out with Python (I had extensive C++ background before that) I also found out I hated the situation when I made typos and found those much later when running my code. However, I solved my problems by using a couple of strategies:

    • Use Pydev plugin for Eclipse and configure Pydev to use Pylint
    • Write lots and lots of unit tests

    The first of these catches most of my typos right there as I make them (and a lot of other errors too), and also provides a pretty good code completion support. I’ve never relied on code completion with any language, so I don’t actually see 100% support as a big deal.

    The second point is good regardless of the programming language, but due to Python’s nature I feel unit tests can cover some of the things you’d otherwise expect a compiler to do. And because Python makes it really easy to create and run unit tests it is a win-win in my opinion.

  2. Tom Davies
    Posted May 3, 2008 at 12:12 pm | Permalink

    Thanks for the tip — I’ve been using Komodo — I’ll see if Pydev and Pylint suit me better.

Post a Comment

Your email is never shared. Required fields are marked *

*
*