I have been working on building a C# class structure to handle Twitter’s API calls for logging in and posting a tweet for a user. A copy of the code is below. Everything works as expected, I am able to obtain a request token, direct the user to the login page, then obtain the users access token. Everything in that section works as expected and well. The trouble begins when I start to use the access token. I am able to use any Twitter endpoint that is a “GET”, IE https://api.twitter.com/1.1/statuses/user_timeline.json, without any issues. Anytime I hit a “POST”, IE https://api.twitter.com/1.1/statuses/update.json, endpoint I get the Error 32. “Could not authenticate you.”
I am at a complete loss. Both the OAuth handshake and the calls with the user access token are using the same functions to build and request the data.
`
private string run_query(Dictionary<string,string> query_params, string url, string method, string token_name, bool multipart_form_submission = false)
{
string auth_header = this.build_auth_header(method.ToUpper(), url, ((multipart_form_submission) ? null : query_params), token_name, multipart_form_submission);try
{
string request_string = "",
body_string = "";
if (query_params != null) {
foreach (KeyValuePair<string, string> p in query_params) {
request_string += ((!String.IsNullOrEmpty(request_string)) ? "&" : "") + UpperCaseUrlEncode(p.Key) + "=" + UpperCaseUrlEncode(p.Value);
body_string += ((!String.IsNullOrEmpty(body_string)) ? "&" : "") + UpperCaseUrlEncode(p.Key) + "=" + UpperCaseUrlEncode(p.Value);
}
if (!String.IsNullOrEmpty(request_string)) request_string = "?" + request_string;
}
System.Net.HttpWebRequest request = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(url + ((!multipart_form_submission) ? request_string : ""));
request.Headers.Add("Authorization", auth_header);
request.Method = method.ToUpper();
if (multipart_form_submission) {
request.SendChunked = true;
request.TransferEncoding = "base64";
}
request.ContentType = (multipart_form_submission) ? "application/octet-stream" : "application/x-www-form-urlencoded";
if (!String.IsNullOrEmpty(body_string) && String.Compare(method.ToLower(), "get") != 0) {
try
{
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
byte[] body_array = encoding.GetBytes(body_string);
request.ContentLength = body_array.Length;
using (System.IO.Stream newStream = request.GetRequestStream())
{
newStream.Write(body_array, 0, body_array.Length);
}
}
catch (Exception) { }
}
System.Net.WebResponse response = request.GetResponse();
return this.read_stream_to_string(response.GetResponseStream());
}
catch (System.Net.WebException ex)
{
return this.read_stream_to_string(ex.Response.GetResponseStream());
}
}
private string build_auth_header(string method, string baseURL, Dictionary<string,string> extraParams, string token_name, bool multipart_form_submission) {
this.header_params = new Dictionary<string, string>
{
{ "oauth_consumer_key", this.consumer_key },
{ "oauth_nonce", this.generate_nonce() },
{ "oauth_signature_method", "HMAC-SHA1" },
{ "oauth_timestamp", ((Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds).ToString() },
{ "oauth_version", "1.0" },
{ "oauth_token", ((this.tokens != null && this.tokens.ContainsKey(token_name)) ? this.tokens[token_name].token : "") }
};
if (String.IsNullOrEmpty(token_name)) this.header_params.Add("oauth_callback", this.callback_url);
if (extraParams != null) {
foreach (KeyValuePair<string, string> p in extraParams) {
if(!String.IsNullOrEmpty(p.Value)) this.header_params.Add(p.Key, p.Value);
}
}
List<string> sorted_keys = this.header_params.Keys.ToList();
sorted_keys.Sort();
string param_str = "";
foreach (string key in sorted_keys) {
string value = this.header_params[key];
if (!String.IsNullOrEmpty(value)) param_str += ((param_str.Length > 0) ? "&" : "") + this.UpperCaseUrlEncode(key) + "=" + this.UpperCaseUrlEncode(value);
}
string
base_string = (multipart_form_submission) ? this.UpperCaseUrlEncode(baseURL) : method.ToUpper() + "&" + this.UpperCaseUrlEncode(baseURL) + "&" + this.UpperCaseUrlEncode(param_str),
crypt_key = this.UpperCaseUrlEncode(this.consumer_secret) + "&" + ((this.tokens.Count > 0 && this.tokens.ContainsKey(token_name)) ? this.UpperCaseUrlEncode(this.tokens[token_name].secret) : ""),
hash = "";
using (var hmac = new HMACSHA1(System.Text.Encoding.ASCII.GetBytes(crypt_key)))
{
byte[] crypt_hash = hmac.ComputeHash(System.Text.Encoding.ASCII.GetBytes(base_string));
hash = Convert.ToBase64String(crypt_hash);
}
this.header_params.Add("oauth_signature", hash);
sorted_keys = this.header_params.Keys.ToList();
sorted_keys.Sort();
param_str = "";
foreach (string key in sorted_keys) {
string value = this.header_params[key];
if (!String.IsNullOrEmpty(value)) {
if (extraParams == null || !extraParams.ContainsKey(key)) param_str += ((param_str.Length > 0) ? ", " : "") + this.UpperCaseUrlEncode(key) + "=\"" + this.UpperCaseUrlEncode(value) + "\"";
}
}
return "OAuth " + param_str;
}`