2016-05-19 8 views
0

Ich arbeite mit einer API, die OAuth 1.0 verwendet. Es gibt keine Dokumentation auf der Website für die API, außer dass sie die Standardmethode verwendet. Ich habe den Leitfaden auf der Twitter-Seite hier https://dev.twitter.com/oauth/overview/creating-signatures verfolgt.Ungültige Signatur mit OAuth 1.0 API

Alles scheint mir gut zu sein, aber ich bekomme immer eine Nachricht, dass ich eine ungültige Signatur habe. Ich habe mit einer Klasse begonnen, die ich auf GitHub gefunden habe, und ich bekam den Signaturfehler. Die Klasse war massiv kompliziert, also schrieb ich meine eigene einfache Klasse (mit C#). Ich habe einen Konstruktor, der alle hier verwendeten Werte richtig setzt. Im 100% sicher, es gibt keine fehlenden Daten, das Problem muss sein, wie die Signatur/Anfrage erzeugt wird, aber soweit ich sehen kann, wurde alles richtig eingerichtet. Der Ausgabe-Header sieht korrekt aus und alles ist ausgefüllt. Irgendwelche Ideen was ist falsch?

public string GenerateHeaderString(string url, string method) 
{ 
    string auth = "OAuth oauth_consumer_key=\"" + ConsumerKey + "\",oauth_token=\"" + HttpUtility.UrlEncode(Token) + "\",oauth_signature_method=\"" + SignatureMethod 
     + "\",oauth_timestamp=\"" + Timestamp + "\",oauth_nonce=\"" + Nonce + "\",oauth_version=\"" + Version + "\",oauth_signature=\"" + GenerateSignature(url, method) + "\""; 
    return auth;    
} 

public string GenerateSignature(string url, string method) 
{ 
    string signature = method + "&" + HttpUtility.UrlEncode(url) + "&" + HttpUtility.UrlEncode("oauth_consumer_key=" + ConsumerKey 
     + "&oauth_nonce=" + Nonce + "&oauth_signature_method=" + SignatureMethod + "&oauth_timestamp=" 
     + Timestamp + "&oauth_token=" + Token + "&oauth_version=" + Version); 
    switch(SignatureMethod) 
    { 
     case "HMAC-SHA1": 
      string keystring = string.Format("{0}&{1}", HttpUtility.UrlEncode(this.ConsumerSecret),HttpUtility.UrlEncode(this.TokenSecret)); 

      var hmacsha1 = new HMACSHA1 
      { 
       Key = System.Text.Encoding.ASCII.GetBytes(keystring) 
      }; 
      byte[] dataBuffer = System.Text.Encoding.ASCII.GetBytes(signature); 
      byte[] hashBytes = hmacsha1.ComputeHash(dataBuffer); 

      this.Signature = HttpUtility.UrlEncode(Convert.ToBase64String(hashBytes)); 
     break; 
    } 
    return this.Signature; 
} 

Antwort

0

Ich glaube, das Problem ist, dass Sie die Signatur URLEncode müssen, bevor Sie es hash. Die ersten beiden Ampersands werden nicht codiert, aber alles andere tut es. Hier ist ein Code, den ich verwende. Das einzige Problem, das ich habe, ist in Fällen, in denen der Querystring Leerzeichen in dem Wert enthält.

 var signatureType = string.Empty; 

     switch (((OAuth1)webRequestDetails.Authentication).SignatureMethod) 
     { 
      case SignatureMethod.HMACSHA1: 
      { 
       signatureType = "HMAC-SHA1"; 
       break; 
       } 
      case SignatureMethod.HMACSHA256: 
       { 
        signatureType = "HMAC-SHA256"; 
        break; 
       } 
      case SignatureMethod.PLAINTEXT: 
       { 
        signatureType = "PLAINTEXT"; 
        break; 
       } 
     } 

     var baseUrl = webRequestDetails.Url; 
     var queryStrings = new List<string>(); 

     var queryStartIndex = baseUrl.IndexOf("?", StringComparison.Ordinal); 
     if (queryStartIndex != -1) 
     { 
      queryStrings = baseUrl.Substring(queryStartIndex + 1, baseUrl.Length - queryStartIndex - 1).Split('&').ToList(); 
      baseUrl = baseUrl.Substring(0, queryStartIndex); 
     } 

     //string builder will be used to append all the key value pairs 
     var stringBuilder = new StringBuilder(); 
     stringBuilder.Append(httpMethod.Method.ToUpper() + "&"); 
     stringBuilder.Append(Uri.EscapeDataString(baseUrl)); 
     stringBuilder.Append("&"); 

     //the key value pairs have to be sorted by encoded key 
     var dictionary = new SortedDictionary<string, string> 
     { 
      {"oauth_version", "1.0"}, 
      {"oauth_consumer_key", ((OAuth1) webRequestDetails.Authentication).ConsumerKey}, 
      {"oauth_nonce", ((OAuth1) webRequestDetails.Authentication).Nonce}, 
      {"oauth_signature_method", signatureType}, 
      {"oauth_timestamp", ((OAuth1) webRequestDetails.Authentication).TimeStamp}, 
      {"oauth_token", ((OAuth1) webRequestDetails.Authentication).Token} 
     }; 

     //merge in the querystrings 
     foreach (var queryString in queryStrings) 
     { 
      var queryStringParts = queryString.Split('='); 
      dictionary.Add(queryStringParts[0], queryStringParts[1]); 
     } 

     foreach (var keyValuePair in dictionary) 
     { 
      //append a = between the key and the value and a & after the value 
      stringBuilder.Append(Uri.EscapeDataString($"{keyValuePair.Key}={keyValuePair.Value}&")); 
     } 

     var signatureBaseString = stringBuilder.ToString().Substring(0, stringBuilder.Length - 3); 

     //generation the signature key the hash will use 
     var signatureKey = 
      Uri.EscapeDataString(((OAuth1) webRequestDetails.Authentication).ConsumerSecret) + "&" + 
      Uri.EscapeDataString(((OAuth1) webRequestDetails.Authentication).TokenSecret); 

     var hmacsha1 = new HMACSHA1(
      new ASCIIEncoding().GetBytes(signatureKey)); 

     //hash the values 
     var signatureString = Convert.ToBase64String(
      hmacsha1.ComputeHash(
       new ASCIIEncoding().GetBytes(signatureBaseString))); 

     return signatureString; 
Verwandte Themen