Skip to content

Instantly share code, notes, and snippets.

@artem1
Last active August 29, 2015 13:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save artem1/8827406 to your computer and use it in GitHub Desktop.
Save artem1/8827406 to your computer and use it in GitHub Desktop.
Tested version of twitter oauth authorization header algorithm, at 2014-02-05. Used for only 2 methods: get request token and exchange request token to access token
private string MakeAuthHeader(string state = null, string token = null, string verifier = null)
{
//kvp for each possible parameter, participating in header or signing
var oauthNonce = new Kvp("oauth_nonce", Convert.ToBase64String(Guid.NewGuid().ToByteArray()));
var oauthCallbackUrl = state != null ? new Kvp("oauth_callback", redirectUrl + "?state=" + state) : null;
var oauthConsumerKey = new Kvp("oauth_consumer_key", consumerKey);
var oauthTimestamp = new Kvp("oauth_timestamp", UnixTimestampUTC().ToString(CultureInfo.InvariantCulture));
var oauthSignatureMethod = new Kvp("oauth_signature_method", "HMAC-SHA1");
var oauthVersion = new Kvp("oauth_version", "1.0");
var oauthToken = token != null ? new Kvp("oauth_token", token) : null;
var oauthVerifier = verifier != null ? new Kvp("oauth_verifier", verifier) : null;
//sign-only parameters (kvp not needed)
var requestUrl = apiUrl + (state != null ? "oauth/request_token" : "oauth/access_token");
const string method = "POST";
var signKey = Uri.EscapeDataString(consumerSecret) + "&" /*+ no token_secret*/;
//signing
var parametersForSigning = string.Join("&", new []
{
oauthNonce, oauthCallbackUrl, oauthConsumerKey, oauthTimestamp,
oauthSignatureMethod, oauthVersion, oauthToken, oauthVerifier
}
.Where(kvp => kvp != null)
.OrderBy(kvp => kvp.Item1)
.Select(kvp => Uri.EscapeDataString(kvp.Item1) + "=" + Uri.EscapeDataString(kvp.Item2)));
var signString = string.Concat(method, "&", Uri.EscapeDataString(requestUrl), "&",
Uri.EscapeDataString(parametersForSigning)); //parameters double percent encoded
var signature = Sign(signKey, signString);
var oauthSignature = new Kvp("oauth_signature", signature);
var headerValue = "OAuth " + string.Join(", ", new[]
{
oauthNonce, oauthCallbackUrl, oauthConsumerKey, oauthTimestamp,
oauthSignatureMethod, oauthSignature, oauthVersion, oauthToken
}
.Where(kvp => kvp != null)
.Select(kvp => Uri.EscapeDataString(kvp.Item1) + "=\"" + Uri.EscapeDataString(kvp.Item2) + "\""));
return headerValue;
}
private static string Sign(string key, string signString)
{
var keyBytes = Encoding.ASCII.GetBytes(key);
using (var hmac = new HMACSHA1(keyBytes))
{
var hash = hmac.ComputeHash(Encoding.ASCII.GetBytes(signString));
return Convert.ToBase64String(hash);
}
}
private static int UnixTimestampUTC()
{
var utcNow = DateTime.UtcNow;
var unixEpoch = new DateTime(1970, 1, 1);
var unixTimestamp = (int)(utcNow.Subtract(unixEpoch)).TotalSeconds;
return unixTimestamp;
}
#region Configuration
private string apiUrl; //https://api.twitter.com/
private string consumerKey;
private string consumerSecret;
private string redirectUrl; //http://localhost:2212/twlogin
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment