这是我到目前为止所做的,但它不起作用,因为我不明白DotNetOpenAuth应该如何工作。我只需要用钥匙签下结果,但我没有运气。一切似乎都指向我需要让客户端授权我的访问权限,但我只需要签名,因为我不需要用户来处理此请求。
请参阅http://developer.netflix.com/docs/read/Security标有“Netflix API请求”
的部分public class class1
{
private void Main()
{
string consumerKey = "<MyAPIKey>";
string consumerSecret = "<MyAPISharedSecret>";
var tokenManager = new InMemoryTokenManager(consumerKey, consumerSecret);
MessageReceivingEndpoint oauthEndpoint =
new MessageReceivingEndpoint(new Uri("http://api-public.netflix.com/catalog/titles/index"),
HttpDeliveryMethods.PostRequest);
WebConsumer consumer = new WebConsumer(
new ServiceProviderDescription
{
RequestTokenEndpoint = oauthEndpoint,
UserAuthorizationEndpoint = oauthEndpoint,
AccessTokenEndpoint = oauthEndpoint,
TamperProtectionElements =
new ITamperProtectionChannelBindingElement[] { new HmacSha1SigningBindingElement()},
},
tokenManager);
var result = consumer.Channel.Request(new AccessProtectedResourceRequest());
}
internal class InMemoryTokenManager : IConsumerTokenManager
{
private Dictionary<string, string> tokensAndSecrets = new Dictionary<string, string>();
public InMemoryTokenManager(string consumerKey, string consumerSecret)
{
if (string.IsNullOrEmpty(consumerKey))
{
throw new ArgumentNullException("consumerKey");
}
this.ConsumerKey = consumerKey;
this.ConsumerSecret = consumerSecret;
}
public string ConsumerKey { get; private set; }
public string ConsumerSecret { get; private set; }
public string GetTokenSecret(string token)
{
return this.tokensAndSecrets[token];
}
public void StoreNewRequestToken(UnauthorizedTokenRequest request, ITokenSecretContainingMessage response)
{
this.tokensAndSecrets[response.Token] = response.TokenSecret;
}
public void ExpireRequestTokenAndStoreNewAccessToken(string consumerKey, string requestToken, string accessToken,
string accessTokenSecret)
{
this.tokensAndSecrets.Remove(requestToken);
this.tokensAndSecrets[accessToken] = accessTokenSecret;
}
public TokenType GetTokenType(string token)
{
throw new NotImplementedException();
}
}
}
答案 0 :(得分:3)
您的实际问题应该是“是否可以使用DotNetOpenAuth签署带或不带访问令牌的请求?”,回答我应该说我不知道的问题,甚至我也找不到它阅读DotNetOpenAuth代码库。
没有单页的文档可用于DotNetOpenAuth,而且代码库非常庞大,以至于您无法阅读它并了解它所支持的内容。
我认为制作未经身份验证的请求不是问题,因为它只是添加到您的请求中的查询字符串参数。
但要签署请求,您需要遵循一个简单的过程:
这些基本上是两类参数,oauth特定参数和Netflix API特定参数。
OAuth特定参数中有nonce
,这是您可以用来生成随机数值的代码:
public static string GenerateNonce()
{
byte[] bytes = new byte[32];
var first = Guid.NewGuid().ToByteArray();
var second = Guid.NewGuid().ToByteArray();
for (var i = 0; i < 16; i++)
bytes[i] = first[i];
for (var i = 16; i < 32; i++)
bytes[i] = second[i - 16];
var result = Convert.ToBase64String(bytes, Base64FormattingOptions.None);
result = new string(result.ToCharArray().Where(char.IsLetter).ToArray());
return result;
}
另一个特定于OAuth的参数是timestamp
,这是您可以用来计算时间戳的代码:
DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds
其他oauth特定参数易于配置,无需为其编写特定代码。
API特定参数是您添加到查询字符串或授权标头(oauth_signature本身除外)或正文请求(如果请求内容类型为application / x-www-form-urlencoded)的任何值。
要创建签名请求或受保护签名,您需要计算签名,除了创建签名密钥的方式外,该签名几乎相同:
要计算签名基本字符串,您需要先将所有参数连接成一个字符串,百分比编码整个字符串。这是帮助您进行百分比编码的代码:
public static string Encode(string source)
{
Func<char, string> encodeCharacter = c => {
if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '.' || c == '-' || c == '_' || c == '~'))
return new string(c, 1);
return EncodeCharacter(c);
};
return string.Concat(source.ToCharArray().Select(encodeCharacter));
}
您还需要按字母顺序对参数进行排序,并使用“&amp;”进行连接。以下是您可能必须编写的代码:
public static string CalculateParameterString(KeyValuePair<string, string>[] parameters)
{
var q = from entry in parameters
let encodedkey = PercentEncode.Encode(entry.Key)
let encodedValue = PercentEncode.Encode(entry.Value)
let encodedEntry = encodedkey + "=" + encodedValue
orderby encodedEntry
select encodedEntry;
var result = string.Join("&", q.ToArray());
return result;
}
让我们调用上面的字符串'参数字符串'。然后,要计算签名基本字符串,您只需要使用'&amp;'将请求的http动词,请求的url和参数字符串连接在一起。您还需要先对百分比进行编码。这是代码:
public static string CalcualteSignatureBaseString(string httpMethod, string baseUri, string parametersString)
{
return httpMethod.ToUpper() + "&" + PercentEncode.Encode(baseUri) + "&" + PercentEncode.Encode(parametersString);
}
创建签名基本字符串后,下一步就是计算签名密钥。
这是将生成签名密钥的代码:
public static string GetSigningKey(string ConsumerSecret, string OAuthTokenSecret = null)
{
return ConsumerSecret + "&" + (OAuthTokenSecret != null ? OAuthTokenSecret : "");
}
在您的情况下,要创建已签名的请求,您只需要为OAuthTokenSecret参数传递null
值。
好的,现在你有了一个签名基本字符串,你现在需要做的就是使用HMAC-SHA1算法进行签名:
public static string Sign(string signatureBaseString, string signingKey)
{
var keyBytes = System.Text.Encoding.ASCII.GetBytes(signingKey);
using (var myhmacsha1 = new System.Security.Cryptography.HMACSHA1(keyBytes)) {
byte[] byteArray = System.Text.Encoding.ASCII.GetBytes(signatureBaseString);
var stream = new MemoryStream(byteArray);
var signedValue = myhmacsha1.ComputeHash(stream);
var result = Convert.ToBase64String(signedValue, Base64FormattingOptions.None);
return result;
}
}
总结一下,这是计算签名的整个过程:
public virtual string GetSignature(string consumerSecret, string tokenSecret, string uri, string method, params ParameterSet[] parameters)
{
var allParameters = parameters.SelectMany(p => p.ToList()).ToArray();
var parametersString = CalculateSignatureBaseString(allParameters);
var signatureBaseString = OAuth1aUtil.CalcualteSignatureBaseString(method, uri, parametersString);
var sigingKey = GetSigningKey(consumerSecret, tokenSecret);
var signature = Sign(signatureBaseString, sigingKey);
return signature;
}
现在您只需要创建一个有效的http请求,并将oauth参数作为“授权”标题添加到请求中。