For my third year project, I have hooked Twisted’s
Perspective Broker authentication into Django, so that a networked
application can authenticate itself against Django’s central user database
(django.contrib.auth). The process is pretty quick and easy, thanks to
Twisted’s pluggable nature, and Django’s pure simplicity.
The Checker
Firstly, we create a class which will actually do the “checking”, to allow access (or not) given a username/password combination. That looks something like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | |
This code is relatively self-explanatory, once you understand Twisted’s way of
doing things. An authenticated “user” in Twisted (though this might not
actually be a person) is called an Avatar. The requestAvatarId method
therefore takes a set of credentials, and returns the Django user object that
corresponds to those credentials (or a failure if necessary). This return value
is wrapped up inside a Deferred, which is something that I won’t go into detail
about in this post. For more information on Deferred objects, this is one area
where the Twisted documentation is quite detailed.
Edit: Fixed a bug in the above code on line 24, thanks to Tom Leys of GridSpy for pointing it out.
The Realm
The next thing we need to do is create a “realm”, which will essentially convert the Django user object into an “avatar” - which is the object that the server will use to communicate with the client:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | |
As you can probably tell, the realm has no responsibility for authentication. It simply accepts a user object (usually a username in normal Twisted apps), and returns an avatar. Here, I’ve written a very simple avatar that will print a message when each user connects and disconnects. The “mind” object allows the server to call remote methods on the client, and is documented (though not in great detail) in the Twisted Perspective Broker Authentication documentation.
Linking Things Together
That’s pretty much it for the authentication code. All that’s left now is to actually link this into a Perspective Broker:
1 2 3 4 5 6 | |
Client Login
To login to a Perspective Broker with authentication enabled is, you’ll be glad to know, very simple:
1 2 3 4 5 6 7 8 9 | |
Hopefully it’s obvious what is going on here. Once we “login” to the factory
providing the connection, a pair of callbacks are added to the deferred - the
connected function will be called if we are successfully logged in, and the
error function will be called if there is some kind of error (like an
UnauthorizedLogin, for example). The success callback will be given the
perspective as the only argument, so it can begin to call methods on the server
in the usual way.
If you’ve solved this particular puzzle in some other way, or if it’s just been of use - then I’d love to hear from you. In any case, this is an excellent example of how simple integration can be when you’re using well documented open source systems. Cheers!