C# Problem obtaining access token


#1

Hi,

I’m trying to request an access token but keep getting a 401 unauthorized response. This is the code I have, please can anyone let me know if there are any obvious problems in any of the steps?

            string oauth_consumer_key = "XXX";
            string oauth_consumer_secret = "YYY";
            string oauth_version = "1.1";
            string oauth_signature_method = "HMAC-SHA1";
            string oauth_url = "https://api.twitter.com/oauth/request_token";
            string oauth_nonce = Convert.ToBase64String(
                                              new ASCIIEncoding().GetBytes(
                                                   DateTime.Now.Ticks.ToString()));
            var timeSpan = DateTime.UtcNow
                                              - new DateTime(1970, 1, 1, 0, 0, 0, 0,
                                                   DateTimeKind.Utc);
            string oauth_timestamp = Convert.ToInt64(timeSpan.TotalSeconds).ToString();
            string oauth_callback = Request.Url.ToString();

            string signatureFormat = "oauth_callback=\"{0}\"&oauth_consumer_key=\"{1}\"&oauth_nonce=\"{2}\"&oauth_signature_method=\"{3}\"&oauth_timestamp=\"{4}\"&oauth_version=\"{5}\"";

            var authSignature = string.Format(signatureFormat,
                                    Uri.EscapeDataString(oauth_callback),
                                    Uri.EscapeDataString(oauth_consumer_key),
                                    Uri.EscapeDataString(oauth_nonce),
                                    Uri.EscapeDataString(oauth_signature_method),
                                    Uri.EscapeDataString(oauth_timestamp),
                                    Uri.EscapeDataString(oauth_version));

            string baseString = string.Format("POST&{0}&{1}", Uri.EscapeDataString(oauth_url), Uri.EscapeDataString(authSignature.ToString()));

            var compositeKey = string.Concat(Uri.EscapeDataString(oauth_consumer_secret), "&"); // wouldn't have auth token when doing authorization, so key should be left like this
            string oauth_signature = "";
            using (HMACSHA1 hasher = new HMACSHA1(ASCIIEncoding.ASCII.GetBytes(compositeKey)))
            {
                oauth_signature = Convert.ToBase64String(
                    hasher.ComputeHash(ASCIIEncoding.ASCII.GetBytes(baseString)));
            }

            string headerFormat = "OAuth oauth_callback=\"{0}\", oauth_consumer_key=\"{1}\", oauth_nonce=\"{2}\", oauth_signature=\"{3}\", oauth_signature_method=\"{4}\", oauth_timestamp=\"{5}\", oauth_version=\"{6}\"";
            var authHeader = string.Format(headerFormat,
                                    Uri.EscapeDataString(oauth_callback),
                                    Uri.EscapeDataString(oauth_consumer_key),
                                    Uri.EscapeDataString(oauth_nonce),
                                    Uri.EscapeDataString(oauth_signature),
                                    Uri.EscapeDataString(oauth_signature_method),
                                    Uri.EscapeDataString(oauth_timestamp),
                                    Uri.EscapeDataString(oauth_version));

            ServicePointManager.Expect100Continue = false;
            HttpWebRequest authRequest = (HttpWebRequest)WebRequest.Create(oauth_url);

            authRequest.Method = "POST";
            authRequest.Headers.Add("Authorization", authHeader);
            authRequest.Headers.Add("Accept-Encoding", "gzip");
            authRequest.ContentType = "application/x-www-form-urlencoded;charset=UTF-8";
            authRequest.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;

            try
            {
                WebResponse authResponse = authRequest.GetResponse(); // errors here
            }
            catch (Exception ex)
            {
            }

#2

It’s hard to tell sometimes just with code what could be going wrong – OAuth has many components that can trip you up – like the current time.

In this case, I’d start with the oauth_version parameter you’re setting – 1.1 is the version of the Twitter API, not the version of OAuth used. We use OAuth version 1.0A, but for the oauth_version value you just stick with “1.0”.

Verify that your system clock is synced to a NTP service or otherwise close to Twitter’s server time (check the Date header on our HTTP responses).

I also really recommend using an OAuth library – the signature generation code you’ve written here is somewhat fragile and wouldn’t work for other stages of use very well.


#3

Hi Taylor,

Thank you for the response. I get the same result using 1.0.

In fiddler, I get the message ‘Failed to validate oauth signature and token’, if that provides any further clue.

The time seems to be correct too.


#4

Taylor - when you say the signature generation is fragile, what is it missing specifically? I tried to follow the procedure on the Twitter dev pages. Also, I only need to do an authentication and make a status update for a logged in user, could the current signature generation code fall on those two cases?

I think I’ll have a closer look at the time issue. Maybe daylight saving is causing a discrepancy.

Thanks