.Net – Twitter Desktop OAuth Authorization

I recent finished the implementation of OAuth into my .Net Twitter library.  I can safely say that it was a pain in the ass.  I have never been so frustrated by “(401) Unauthorized” errors.  But alas, I was able to complete the implementation.

As a guideline, I used Shannon Whitley’s code, since that’s the only .Net reference Twitter gives for OAuth implementation.  Since I had already created my own Twitter library that consumed 95% of the current Twitter REST API methods, I couldn’t simply add his two code files to my project and run with it.  I had to change some stuff around to get it to work with mine.  I also made some modifications to his class that makes all of the OAuth implementations.  In my opinion, it had a lot of code that didn’t need to be there.  I also created another class to consume the parameters needed for the OAuth requests so that I wasn’t passing 9 parameters to different methods.

So first, I want to explain OAuth a little and how it works for a desktop Twitter client.  I stress desktop application because Twitter has different implementations for web clients vs. desktop clients.

So OAuth is an open protocol to allow secure authorization to an API.  This means that for Twitter, the user’s of a desktop client aren’t required to give their username and password to the client.  The client can use OAuth to communicate with with the Twitter API without needing usernames and passwords.

Now for the process.  This was the toughest part for me to get my head around.  I couldn’t really find any good explanations of each step of the process.  So I will explain as much as I can.

Your first step is to register your application with Twitter.  This does a couple of things.  It gives you a “Consumer Key” and “Consumer Secret”.  These are needed in each OAuth request that is made.  This also provides the “source” for the tweets.  Twitter recently removed the ability to set the “source” of the tweet to your application name when using Basic Authentication.  This is now only allowed when using OAuth.

When making requests to OAuth methods, there are a number of parameters that are required for all requests.  And depending on the request, some may be expecting additional parameters.  The required parameters for all requests are:

1.  Consumer Key – given when you register your application.
2.  Nonce – a random string.  I use a GUID.  Some use a random number.
3.  Timestamp – the number of seconds since January 1, 1970.
4.  Signature – an HMAC-SHA1 string of all of the other parameters.
5.  Signature Method – HMAC-SHA1.  Currently Twitter only supports HMAC-SHA1.
6.  Token – unauthorized/request/access token.
7.  Verifier – the PIN from the Desktop Workflow
8.  Version – “1.0″

When creating the signature, you will use the Consumer Secret and Token Secret as the key.  Also, the parameters that are part of the signature need to be in order when creating the signature and when making the request.  The signature is appended to the end of the parameters so it does not need to be in order.

Here is the order that the parameters need to be in:

1.  oauth_consumer_key
2.  oauth_nonce
3.  oauth_signature_method
4.  oauth_timestamp
5.  oauth_token
6.  oauth_verifier
7.  oauth_version
8.  oauth_signature

To make the signature, you would use this code:

HMACSHA1 hmacsha1 = new HMACSHA1();
hmacsha1.Key = Encoding.ASCII.GetBytes(string.Format("{0}&{1}", UrlEncode(oauth.CustomerSecret), string.IsNullOrEmpty(oauth.TokenSecret) ? "" : UrlEncode(oauth.TokenSecret)));
// code to compute the hash to return as the signature

Moving to the code, your first step is to send an HttpWebRequest to http://twitter.com/oauth/request_token .  This request will return an Unauthorized Token and Unauthorized Token Secret.  In the current library that I used(and my Twitter API library), this method will return the entire URL including the token and secret, which will look like this…

http://twitter.com/oauth/authorize?oauth_token=UnauthorizedTokenValue

Your next step is to have the user go to the URL that was returned from the previous step.  This is the step that many developers have complained about.  When navigating to this URL, the user will enter their username and password.  They will then be given a PIN.  You will need to get this PIN from the user because it is required for you to get an Access Token.  I simply give a textbox for the user to copy and paste to.

After receiving the PIN, you will now need to make a request to http://twitter.com/oauth/access_token .  This will give you the Access Token that you will need to make all other requests to the Twitter REST API.  You will need to save these somewhere, whether it be in a database or in a file.

Here is some client code..

TwitEclipseAPI twit = new TwitEclipseAPI();
twit.OAuthConsumerKey = ""; // your consumer key
twit.OAuthConsumerSecret = ""; // your consumer secret

// Once you get the access token, this
//    would be out to set it
//twit.OAuthAccessToken = "";
//twit.OAuthAccessTokenSecret = "";

string redirectURL = twit.OAuthGetUnauthorizedRequestToken();
Process.Start(redirectURL);

// show a popup to enter PIN
frmEnterPIN f = new frmEnterPIN();
f.ShowDialog();
string pin = f.PIN;
f.Dispose();

if (twit.OAuthRequestAccessToken(pin))
{
   twit.UpdateUserStatus("This is a test");
}

I have posted a link to the code files for my library and how it uses the edited version of Shannon’s library.

Post any questions in the comments.  I will answer them as best I can.  If  you run into any issues, please let me know.  Thanks.

UPDATE: I have update the site with a new version of my twitter library.  I have also moved the download to CodePlex so that it will be easier for me to update.  Here is the link.


Tagged: , , , , ,

12 Comments

  1. doubin September 30, 2009 2:38 pm  Reply

    Hi

    The I appreciated this post component sounds promising but I was unable to down load the API.

    Thanks

    • Ryan Alford September 30, 2009 3:12 pm  Reply

      Do you get an error message? I was just able to download it without an issue. I just clicked on the “Download” toward the end of the post, and it worked fine.

  2. Polprav October 16, 2009 8:25 am  Reply

    Hello from Russia!
    Can I quote a post in your blog with the link to you?

    • Ryan Alford October 16, 2009 8:51 am  Reply

      Yes.

  3. Cleothildee November 24, 2009 8:09 am  Reply

    i love to Twitter my day to day activities to my friends and followers. Twitter is much better than blogging because it is direct to the point and does not require you to type so many unnecessary words.

    1c

  4. sweet tweet December 16, 2009 8:22 pm  Reply

    What is the values I need to save in the database? Is it only the PIN?

    And could you explain the commented code:
    // Once you get the access token, this
    // would be out to set it
    //twit.OAuthAccessToken = “”;
    //twit.OAuthAccessTokenSecret = “”;

    Didn’t understand what that was for.

    Thx for a nice api though.. Gonna start using yours now

  5. Ryan Alford December 17, 2009 9:26 am  Reply

    No, you don’t need to save the PIN. Once you use the PIN to get the Token and TokenSecret, it’s not needed anymore.

    Those commented out lines are no longer used. My api will now set those values when the request is done. For debugging before I got my database storing working, I was hardcoding the token and secret so that I didn’t have to keep doing the PIN.

    I am about to make another post with an update version of the API. Tons of changes have been made since, hopefully for the better.

  6. WP Themes February 1, 2010 5:52 pm  Reply

    Good post and this mail helped me alot in my college assignement. Thanks you as your information.

  7. Patria Beurskens April 27, 2010 11:58 am  Reply

    I love to use Twitter whenever i want to know the latest buzz about my friends. I also use Twitter to know the latest buzz from famous persons :

  8. Dwayne Macadangdang September 21, 2010 5:50 pm  Reply

    I appreciate all your work on this.

    I’m using VS 2010 and I added your DLL as a reference; The TwitEclipseAPI reference shows in my solution explorer, however, I can’t set a “using TwitEclipseAPI;” statement.

    Any suggestions?

    Thanks in advance,

    Dwayne

  9. Lieselotte Lavoy January 27, 2012 6:35 am  Reply

    Whats up, there is always some fantastic material in this article. I simply wanted to express gratitude for sharing and that also I’m in fact a really big admirer of the web site. I started out browsing this a few months ago, we merely wanted to say thanks. Many thanks for allowing my remark and also much love!

  10. Shiloh Melberg March 13, 2012 7:15 am  Reply

    5 Centimeters Per Second is a little slow, but the art is so beautiful.

Leave a comment

Your email address will not be published. Required fields are marked *