[Twisted-Python] Implementing OAuth in twisted.cred

Glyph Lefkowitz glyph at twistedmatrix.com
Mon Jul 5 13:48:01 EDT 2010

On Jul 3, 2010, at 3:19 PM, Laurens Van Houtven wrote:

> A number of people have tried to implement it in Twisted. AFAICT most
> of them just use oauth.py. That uses urllib. Basically I guess it just
> crosses its fingers and hopes that the OAuth API endpoints will always
> be reachable and responsive. (I have been told this is completely
> unrealistic.)

It always is.

> Thankfully, the OAuth spec is asynchronous in nature. I'm trying to
> implement OAuth using twisted (specifically twisted.cred and
> twisted.web) to promote code re-use.


> In order to do the authentication OAuth relies on redirection (in most
> use cases, this is HTTP redirection), which would be protocol
> specific. I'm not sure how twisted.cred fits into this since it
> appears to expect everything beyond the portal to be
> protocol-agnostic.

Not at all.

Checkers are as protocol-specific as necessary.  That's why they have a credentialInterfaces attribute, to indicate what type of credentials they may be used with.

Now, many *application* protocols do share obvious checker behavior such as "does this password match", and it would be a shame to re-implement that logic, but that's not to say that *authentication* protocols shouldn't have their own, more specific interfaces.  Especially if you could see some way to abstractly re-implement, let's say, SMTP authentication to rely on OAuth.

As someone else already noted in a reply, the main thing is that this stuff returns a Deferred, so HTTP redirection could be neatly handled there.

> I'm not sure what the credentials would be.

I'm not going to read 40 pages of RFC just to answer this one email :) but the credentials object should be something that contains enough information for the checker to do its work.

What the checker needs to be able to do is to map the credentials into a locally useful "avatar ID".  This is probably just an URI which identifies the authenticated principal (which presumably the IRealm could use to map into a local database row).

Of course it would be *good* if you could boil down OAuth credentials to something simple that could be re-used by other protocols, or better yet some existing interface.  Then you could use an existing checker, or perhaps even provide a strcred plugin.  But, that seems unlikely, given that its domain model for authentication is a bit broader than the usual username/password check.

> If I understand correctly the avatar would be the thing that has the
> token credentials (for those who haven't read the OAuth spec, "token
> credentials" are an OAuth thing, and not necessarily the credentials
> in the twisted.cred sense); it represents a single authenticated
> transaction (which might consist of many authenticated requests). This
> takes care of steps 6 7 and 8 in
> http://twistedmatrix.com/documents/current/core/img/cred-login.png.

The avatar is made entirely of application logic.  It shouldn't have any authentication stuff stuck to it at all.  (Although maybe that's not what "token credentials" means...)  Please note that it must be an implementation of an _existing_ protocol interface, as that's the whole point of cred's abstraction: to allow existing application logic to be re-used independent of authentication or authorization mechanism.  If this is an authentication mechanism for an HTTP protocol, the avatar is an IResource provider.  HTTP already has a defined avatar interface within Twisted, and that's it; so if you want to use any existing code that talks to cred, you have to use it.

If the avatar needs to be passed more information in order to operate correctly, then you can pass that information as part of the avatar ID somehow, and have the realm implementation break it down into the necessary parts to pass on.  This is, admittedly, a crufty corner of cred, but that's the best option available right now.  Hopefully OAuth doesn't require this :).

> The strange bits start in the CredentialsChecker, since credentials
> are checked by someone else entirely.

A credentials checker doesn't need to actually check the credentials itself; it's just the logic that knows who to delegate to and what information to give them.

> I really don't understand the Mind, but it sounds like something that
> might be required in the context of a three-actor auth system like
> OAuth.

The Mind is for connection-oriented protocols to provide a callback mechanism to the originating side of the connection.  For example, if I'm logging in to an IRC server, the 'mind' would be a wrapper around the client connection that would allow the avatar to be associated with a TCP socket it could send IRC messages to.  I don't think it applies in this case.

> I would be really grateful if someone who actually understood
> twisted.cred (and hopefully also OAuth) could shed some light on this.

I hope this has been more useful than confusing.  Let me know if you have more questions.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://twistedmatrix.com/pipermail/twisted-python/attachments/20100705/081cdf28/attachment.htm 

More information about the Twisted-Python mailing list