6

Continuation from Get twitter public timeline, json+C#, no 3rd party libraries

I'm still new to C# and oAuth so please bear with me if I fail to understand anything

I've created a C# class named oAuthClass, and these are the variables I currently have:

    static class oAuthClass
{
    public static void run()
    {
        int oauth_timestamp = GetTimestamp(DateTime.Now);
        string oauth_nonce = PseudoRandomStringUsingGUID();
        string oauth_consumer_key = "consumer key here";
        string oauth_signature_method = "HMAC-SHA1";
        string oauth_version = "1.0";
    }
}

I've read up on OAuth Signatures, and I chose to use HMAC-SHA1 for now, I don't know how to generate the signature, I'm also extremely confused after reading and seeing stuff like HTTP-Encodings and Base-Strings and whatnot (I've no idea what they mean at all), but my guess is to create a URL that's "Http-encoded", like spaces->"%20"?

In summary: -What are base-strings?

-Am I right on the spaces->%20 example?

-HMAC-SHA1 involves a message and a key, is the consumer secret the message? Is the consumer key the key then?

-How to create a signature through the use of the HMAC-SHA1 algorithm

-If I do manage to create the signature, how do I pass these values to Twitter?

I could use

http://example.com?consumer_key=asdf&oauth_signature=signaturevalue&etc., 

but I've read and apparantly people use HTTP-Headers or something (again, I don't really know what this is)

Thank you! Again, no 3rd party libraries allowed :(

Community
  • 1
  • 1
Procrastinatus
  • 121
  • 2
  • 12

2 Answers2

14

It is really hard to answer your question in a short manner, since implementing a full blown OAuth client is not trivial and requires really understanding the OAuth1.0a specification. It is not rocket science but it really requires sorting out all the bits and pieces.

I will attempt to answer your question piecemeal.

What are base strings?

A signature base string in OAuth is built like this:

  • Start with the HTTP method of the request your are sending, in upper case. E.g POST or GET.
  • Add an ampersand (&) character to that
  • Add the URL encoded (percent encoded) URL you are calling in your request (do not include parameters here)
  • Add yet another ampersand (&) character here
  • Lastly add the URL encoded parameter string

I'll describe how to create the parameter string you need in that last step.

Gather all the parameters included in the request. You'll find them either in the URL as part of the query string and also in the request body when you are POST-ing requests. Say for example that you are POST-ing the parameter parameter1=value1 to the URL http://example.com/?parameter2=value2. That makes two parameters to include.

Now you also have to sum up all the OAuth parameters that are needed for the protocol to be happy. These would lead to a parameter list looking something like this:

  • oauth_consumer_key=fffffaaaafffaaaff
  • oauth_nonce=aaaaabbbbbcccccaaaaudi2313
  • oauth_signature_method=HMAC-SHA1
  • oauth_timestamp=1319633599
  • oauth_token=bbbbbbbbbfsdfdsdfsfserwerfsddffdsdf
  • oauth_version=1.0
  • parameter1=value1
  • parameter2=value2

All these individual strings need to be lexicographically sorted on the parameter name (alphabetically should suffice), and concatenated into a string. That's your parameter string.

Am I right on the spaces->%20 example?

Yes. You are talking about percent encoding, which also goes by the name of HTTP encoding and URL encoding. http://en.wikipedia.org/wiki/Percent-encoding.

HMAC-SHA1 involves a message and a key, is the consumer secret the message? Is the consumer key the key then?

The message is the signature base string that you created above. And the key is the combination of your consumer secret and your access token secret. So the key should look like this: CONSUMER_SECRET&TOKEN_SECRET (notice the ampersand). In the absolute first request that you do you will not have a token secret yet, then the key is only CONSUMER_SECRET& (again, notice the ampersand).

How to create a signature through the use of the HMAC-SHA1 algorithm.

I fetched this from http://oauth.googlecode.com/svn/code/csharp/OAuthBase.cs and the secrets and the base string are assumed to be available to the code.

Basically feed an HMACSHA1 instance with a key and a message, render that hash and convert it to a base64 string.

HMACSHA1 hmacsha1 = new HMACSHA1();
hmacsha1.Key = Encoding.ASCII.GetBytes(string.Format("{0}&{1}", UrlEncode(consumerSecret), string.IsNullOrEmpty(tokenSecret) ? "" : UrlEncode(tokenSecret)));
byte[] dataBuffer = System.Text.Encoding.ASCII.GetBytes(signatureBaseString);
byte[] hashBytes = hmacsha1.ComputeHash(dataBuffer);

return Convert.ToBase64String(hashBytes);

If I do manage to create the signature, how do I pass these values to Twitter?

You should easily be able to research what an HTTP header is.

But you can choose to add the final result of the parameters and signature to the URL, I think Twitter even accepts them in the request body on some requests. But the preferred way is through the Authorization HTTP header since it allows for clear separation between protocol specific and request specific parameters.

It should look somewhat like this (taken straight from the OAuth 1.0a spec):

Authorization: OAuth realm="Example",
    oauth_consumer_key="0685bd9184jfhq22",
    oauth_token="ad180jjd733klru7",
    oauth_signature_method="HMAC-SHA1",
    oauth_signature="wOJIO9A2W5mFwDgiDvZbTSMK%2FPY%3D",
    oauth_timestamp="137131200",
    oauth_nonce="4572616e48616d6d65724c61686176",
    oauth_version="1.0"
Community
  • 1
  • 1
Jon Nylander
  • 8,743
  • 5
  • 34
  • 45
  • Thank you, this is a lot more than I could've ask for! I'll try as hard as I can to get this working. If I have any further problems(still related to this question) should I start a new question or continue asking here? I'll try before asking though! Also, how do I mark a question as solved, or does ticking an answer suffice? Once again, thank you for this post! I hope it helps other people attempting to do the same as well :) – Procrastinatus May 22 '12 at 17:42
  • Comment here if you run into troubles, and I'll try to help. We can also use the chat function. Also, twitter's dev resources are gold, use them to learn both about OAuth and their API. – Jon Nylander May 22 '12 at 18:46
  • http://oi45.tinypic.com/6e0mcl.jpg - Screenshot of the baseString and the url encoded hash Is everything up to this point correct? I'm still only trying to get the request_token part done for now I guess HTTP headers are a place for key-value pairs? I'm not entirely sure how to create those though, create a new httpwebrequest object, then...? – Procrastinatus May 23 '12 at 17:56
  • The base string looks correct except that the ampersands between the parts should not be encoded. Encode the individual parts, then concatenate with &. – Jon Nylander May 23 '12 at 18:29
  • Alright, I excluded the ampersands in the url encoding method, how do I pass the values through the authorization header now? WebClient wc = new WebClient(); wc.Headers.Add("??","??");...?? – Procrastinatus May 24 '12 at 06:29
  • I am not into the C#. But yes, in essence that's how adding headers to an outgoing request usually looks like. – Jon Nylander May 24 '12 at 12:02
  • I tried putting the parameters as part of the URI https://api.twitter.com/oauth/request_token?oauth_signature=o%2BoKhXQ4fQ60KlP788W4UCuywFE%3D&oauth_consumer_key=1Mz8I25Vn0D1Nq8uyJR0wA&oauth_nonce=3e9d76PcekO8Zc3r/WWsCg&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1337881337&oauth_version=1.0&oauth_callback=oob it still shows "Failed to validate oauth signature and token", why is that? – Procrastinatus May 24 '12 at 17:43
  • I cannot see any reason why your request should not work, I checked https://dev.twitter.com/docs/api/1/post/oauth/request_token, and it looks like it should work with a GET request and oauth_parameters in the URI. But either your signature is not correct, or maybe your computer's clock is not correct. Check out: http://blainegarrett.com/2009/07/14/failed-to-validate-oauth-signature-and-token-on-twitter-oauth-check-your-cloc/ – Jon Nylander May 24 '12 at 21:49
  • Also, remember that any request that you formulate will only be usable once, since the oauth_nonce needs to be unique for every request. So if you try the same twice, the second will fail. And if you wait between formulating the request and actually sending the request, you run the risk of the oauth_timestamp to have become invalid. Both probably resulting in the error you are seeing. – Jon Nylander May 24 '12 at 22:08
  • Alright, I managed to get the tokens and secrets required for a full oauth signed request, but I'm confused, I posted another question, it's a continuation http://stackoverflow.com/questions/10819229/twitter-oauth-flow-confused-about-oob-3-legged-auth-and-general-flow-dont-ne – Procrastinatus May 30 '12 at 15:18
0

If you are really confused and just want a simple Library to use I would suggest to look into Twitterizer

There documentation has examples and it is pretty easy to set up.

[EDIT] oops, sorry just read that you are not looking for 3rd party libraries. Sorry

Ryan Drost
  • 1,184
  • 10
  • 19
  • I was successful with using Twitterizer before, but realised I couldn't use 3rd party libraries in my project only recently so...you know the rest, thanks though! – Procrastinatus May 21 '12 at 16:44