October 2011 Archives

I got an email the other day from Pedro Félix, asking for my thoughts on an OAuth scenario that he was wondering about and discussing with Howard Dierking. As Pedro and I talked, I learned that he had a really interesting problem on his hands. Basically, he wanted to create an OAuth 2.0 protected service that called an OAuth 1.0a protected service (e.g., Twitter). So, what he had on his hands was a bunch of clients, tokens, services, and two different protocols that do things similarly but w/ slightly different names. Very confusing stuff.

To begin making sense of all this, it's helpful to list out what we know:

  • Pedro wants to call the Twitter API from his own API.
  • The Twitter service is an OAuth 1.0a Resource Server (RS).
  • Twitter has an OAuth 1.0a Authorization Server (AS).
  • The Twitter service naturally only trusts it's own AS.
  • Pedro's service is an OAuth 2 RS and an OAuth 1.0a Twitter client.
  • Pedro has an OAuth 2 AS.
  • Pedro's service naturally only trusts his own AS.
  • The Web app that calls Pedro's service is an OAuth 2.0 client and must submit Access Tokens (ATs) emitted by his own AS (not Twitter's) when calling his service.
  • The Resource Owner (RO) is a Twitter user and will authorize Pedro's service to call the Twitter API to modify their data.
  • The RO authenticates to Pedro's AS using Twitter's OAuth 1.0a AS.
  • Pedro's AS asks the RO to authorize the third-party client to access his service which in turn will access Twitter's.

With these basics in mind, have a look the the following picture that presents an overview of the actors involved:

oauth-to-oauth2.gif


Now, to get an idea of how Pedro's service would call Twitter's, flip through animations in the following slide deck.

See how one OAuth protected resource can call another? Pretty cool stuff! It's also cool that if instead Pedro wanted to call the Facebook graph API which uses OAuth 2, it would work almost the exact same way. As if that we're cool enough though, what's even cooler is that this isn't just theory. I was able to implement this in PingFederate in about half the time it took me to write this blog post! If I have some time over the weekend when I'm not celebrating my little one's second birthday, I'll try to post a screencast.

Anyway, thanks Pedro and Howard for inviting me into your conversation. If you or anyone else has questions about this or other OAuth matters, please feel free to post a comment here or send me a mail.
The other day I wrote about a way to use OAuth w/ mobile apps that was not susceptible to phishing and does not use the password anti-pattern. I just had to code it up and make sure it worked. What better time then 4 AM when the house is quite? Ah, jet leg ;-)

Using Lars Vogel's tutorial on C2DM, PingFederate's new OAuth server, and a little Python Web app running on CherryPy, I found that it does actually work! Here's the high-level points to be aware of if you want to implement this:

  • The C2DM API is in beta, and you'll need to sign up for access using a Google account. Developer accounts have a limited quota.
  • You need to provide the email address you sign up w/ and a password to the Google ClientLogin service to get an OAuth-like Access Token (AT). You don't have to use your own password though; you can create one specifically for this purpose (which you'll have to do if you're using 2FA w/ your account like I am).
  • These tokens need to be renewed every so often, so, in your Web app, keep an eye out for errors. (It's not indicated by the HTTP status code but the contents of the body IIRC.)
  • PingFederate's OAuth token endpoint is configured w/ a self-signed SSL cert by default, so you'll need to work around that during development.
  • There can be a bit of leg between the time you publish the OAuth Access Code (AC) and the time your app gets the message. Meanwhile, your user will be looking at a blank white browser window. To avoid this second or so delay, you can register a customer scheme in your app. Then, in the helper Web app, return a 302 to that as soon as you send the AC to the Google C2DM service. This will cause the app to come to the foreground immediately. Alternatively, put a little spinner in the Web page.
That's basically it. If you follow Lars' tutorial and keep these things in mind, I'm sure you'll be up and running in no time -- especially if you've woken up before anyone else and it's really quite out ;-) Here's a little demo of it running that will hopefully motivate you to get it coded up too. If you get stuck, drop me a note.