OAuth allows users to hand out tokens instead of credentials to access their data
hosted by a given service provider. Each token grants access to a specific site
(e.g. Twitter) for specific resources (e.g. only getting timeline) and for a
defined duration (e.g. the next 2 hours). This allows a user to grant a third
party site access to their information stored with another service provider,
without sharing their access permissions or the full extent of their data.
The OAuth development process was started in 2005, and has since matured to spec
1a, which includes modifications to ensure adequate security.
OAuth is a service that is complementary to, but distinct from, OpenID.
OAuth has been compared to luxury cars today that come with a valet key. This is
a special key you give the parking attendant and unlike your regular key, will
not allow the car to drive more than a mile or two. Some valet keys will not
open the trunk, while others will block access to your onboard cell phone address
book. Regardless of what restrictions the valet key imposes, the idea is the
same. You give someone limited access to your car with a special key, while using
your regular key to unlock everything.
This is what OAuth does; it allows you the User to grant access to your private resources
on one site (which is called the Service Provider), to another site (called Consumer,
not to be confused with you, the User). While OpenID is all about using a single
identity to sign into many sites, OAuth is about giving access to your stuff
without sharing your credentials at all.
The OAuth process
The end goal with OAuth is to get an access token and secret. Once you have these,
requesting a user's information is much like it would be with HTTP Basic Authentication.
Tokens and Secrets
There are three sets of pairs each made up of a token and a secret. Each set builds
upon the previous one. The three sets are consumer, request and access.
The consumer token and secret are provided for you by the OAuth provider, when you
register an application (such as with Twitter). These define what application
is attempting to do the operation.
In order to get the access token, you have to create a request token, keep track
of it, and then you redirect the user to the provider to authorize your application.
The other thing that the request token provides is an authorization URL. The authorization
URL is where your application redirects to, to allow the user to grant or deny
you access to the their data. The application also provides a callback URL so
that the service knows where to send the user once they've authorized you.
Before you redirect, you must store the request token and secret as you’ll need those
to create the access token when the user returns to your application. Once the
user is back at your app, you use the request token and secret to generate the
access token.
Once you have an access token pair, all you need are the consumer key and consumer
secret, combined with the AccessToken and AccessSecret, and as long as the user
doesn't revoke access, you can continue to make API calls on the user's behalf.
It's important to note that at no time do you ever gain access to the user's credentials.
That's the main security advantage of using oAuth.
In this sample app, which is a slightly modified version of the OAuthLib Sample from
Codeplex.com, we will use the Consumer Key and Consumer Secret to allow Dr. Dexter
Dotnetsky's "ReadOnly Timeline app" to get our user timeline. (Dexter
doesn't do much with his Twitter account other than to post a tweet for each
new article that is published on eggheadcafe.com; we generally try to leave him
alone as he can get quite cranky.)
At any rate, Dexter was kind enough to provide us with the required Consumer Key
and Consumer Secret, which is all we need to get an Access Token. Now here's the code:
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.Net;
using OAuthLib;
namespace OAuthDevSupport
{
class Program
{
static void Main(string[] args)
{
try
{
/// this is Dexter Dotnetsky Application - Read Only
// 1) Create a Consumer with the Consumer Key and Consumer Secret
Consumer c =
new Consumer("9pjjXRfv15nFc1mGwajtg", "PqlExhCeUKkwSxPvIqE1bVhO4bRYyw41XK0n42Vhk");
// 2) Get a Request Token
RequestToken reqToken =
c.ObtainUnauthorizedRequestToken("http://twitter.com/oauth/request_token", "http://twitter.com/");
// 3) Start a process and bring up the browser with the authorization page
Process.Start(
Consumer.BuildUserAuthorizationURL("http://twitter.com/oauth/authorize",reqToken
)
);
Console.Out.WriteLine("Enter Input verifier");
// 4) Get the oAuth verification code the user entered
String verifier = Console.In.ReadLine();
verifier = verifier.TrimEnd('\r', '\n');
// 5) Get an Access Token
AccessToken accessToken =
c.RequestAccessToken(verifier, reqToken, "http://twitter.com/oauth/access_token", "http://twitter.com/");
Console.WriteLine("Token Value: " + accessToken.TokenValue);
Console.WriteLine("Token Secret: " + accessToken.TokenSecret);
// Note The Access Token and Secret, combined with the Consumer Key and Consumer
secret,
// are all we need from now on to use this app.
HttpWebResponse resp =
c.AccessProtectedResource(
accessToken,
"http://twitter.com/statuses/user_timeline.xml",
"GET",
"http://twitter.com/",new Parameter[]{ }
);
byte[] b = new byte[resp.ContentLength];
resp.GetResponseStream().Read(b, 0, b.Length);
String s = System.Text.Encoding.UTF8.GetString(b);
Console.WriteLine(s.Substring(0,3000));
Console.ReadLine();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
}
The sample will output the Access Key and Secret that it gets, along with the first
3000 bytes of your timeline. In this case, we provide no callback url, only
"oob" which is what gives us the browser page with the PIN code that
you copy and enter into the Console App. There is more about the OAuth process for Twitter here including a nice process flow diagram.
You can find OAuth built into a number of Twitter client codebases:
twitterizer http://code.google.com/p/twitterizer/
tweetsharp http://tweetsharp.codeplex.com/
Linq to twitter http://linqtotwitter.codeplex.com/ (one of my favorites)
and others.
You can download the demo Visual Studio 2010 Solution Here.