Vimeo API を使用しようとしていますが、署名の生成に問題があります....
基本的に私はこのクラスを持っています
public class OAuthParameters
{
public string RedirectUrl { get; set; }
public string ClientId { get; set; }
public string ClientSecret { get; set; }
protected string NormalizeParameters(SortedDictionary<string, string> parameters)
{
StringBuilder sb = new StringBuilder();
var i = 0;
foreach (var parameter in parameters)
{
if (i > 0)
sb.Append("&");
sb.AppendFormat("{0}={1}", parameter.Key, parameter.Value);
i++;
}
return sb.ToString();
}
private string GenerateBase(string nonce, string timeStamp, Uri url)
{
var parameters = new SortedDictionary<string, string>
{
{"oauth_consumer_key", ClientId},
{"oauth_signature_method", "HMAC-SHA1"},
{"oauth_timestamp", timeStamp},
{"oauth_nonce", nonce},
{"oauth_version", "1.0"}
};
var sb = new StringBuilder();
sb.Append("GET");
sb.Append("&" + Uri.EscapeDataString(url.AbsoluteUri));
sb.Append("&" + Uri.EscapeDataString(NormalizeParameters(parameters)));
return sb.ToString();
}
public string GenerateSignature(string nonce, string timeStamp, Uri url)
{
var signatureBase = GenerateBase(nonce, timeStamp, url);
var signatureKey = string.Format("{0}&{1}", ClientId, "");
var hmac = new HMACSHA1(Encoding.ASCII.GetBytes(signatureKey));
return Convert.ToBase64String(hmac.ComputeHash(new ASCIIEncoding().GetBytes(signatureBase)));
}
}
これを呼び出すコードは別のクラスにあり、このメソッドがあります
public string GetAuthorizationUrl(string Url)
{
var sb = new StringBuilder();
var nonce = Guid.NewGuid().ToString();
var timeStamp = (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds.ToString();
var signature = parameters.GenerateSignature(nonce, timeStamp, new Uri(Url));
sb.Append(GenerateQueryStringOperator(sb.ToString()) + "oauth_consumer_key=" + Uri.EscapeDataString(parameters.ClientId));
sb.Append("&oauth_nonce=" + Uri.EscapeDataString(nonce));
sb.Append("&oauth_timestamp=" + Uri.EscapeDataString(timeStamp));
sb.Append("&oauth_signature_method=" + Uri.EscapeDataString("HMAC-SHA1"));
sb.Append("&oauth_version=" + Uri.EscapeDataString("1.0"));
sb.Append("&oauth_signature=" + Uri.EscapeDataString(signature));
return Url + sb.ToString();
}
private string GenerateQueryStringOperator(string currentUrl)
{
if (currentUrl.Contains("?"))
return "&";
else
return "?";
}
(認証トークンを取得するために) 渡している URL はhttps://vimeo.com/oauth/request_tokenですが、これを呼び出すたびに次のエラーが表示されます
401 Unauthorized - Invalid signature - The oauth_signature passed was not valid.
これは私を夢中にさせています。何が問題を引き起こしているのかわかりません。
誰かが私に助けを与えることができれば、それは素晴らしいことです.
更新 1
Uri.EscapeDataString を使用することは、文字列をエンコードする正しい方法ではないと誰かが述べました。EscapeDataString を移動する前に、この関数を使用していました。
protected string UrlEncode(string unencodedString)
{
var encodedString = new StringBuilder();
var unreservedChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~";
foreach (char symbol in unencodedString)
if (unreservedChars.IndexOf(symbol) != -1)
encodedString.Append(symbol);
else
encodedString.Append('%' + String.Format("{0:X2}", (int)symbol));
return encodedString.ToString();
}
しかし、これはまだ役に立ちません。また、http://hueniverse.com/oauth/guide/authentication/を使用しても、問題の原因についての洞察は得られませんでした:(
更新 2
それで、hueniverse でコードを実行したところ、タイムスタンプが正確ではない (小数点以下の桁数があった) ことがわかったので、この関数を使用してタイムスタンプを生成する方法を変更しました。
public string GenerateTimeStamp()
{
TimeSpan ts = DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1, 0, 0, 0, 0));
string timeStamp = ts.TotalSeconds.ToString();
timeStamp = timeStamp.Substring(0, timeStamp.IndexOf("."));
return timeStamp;
}
したがって、基本署名を見ると、次のようになります。
POST&https%3A%2F%2Fvimeo.com%2Foauth%2Frequest_token%2F&oauth_consumer_key%3Dmykey%26oauth_nonce%3D66c80d6b-9ff6-404b-981b-56f40f356a31%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1370444366%26oauth_token%3D%26oauth_version%3D1.0
Hueniverse から生成されたものと比較すると、次のように生成されます。
POST&https%3A%2F%2Fvimeo.com%2Foauth%2Frequest_token%2F&oauth_consumer_key%3Dmykey%26oauth_nonce%3D00b81872-688b-4184-a978-206e5fbcc531%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1370446860%26oauth_token%3D%26oauth_version%3D1.0
生成された文字列の長さが許容範囲であれば、正確です。私の次のテストは、まったく同じタイムスタンプを作成し、すべてが同じ署名を生成するかどうかを確認することです....