使用.NET通过Amazon AWS Product Advertising API按ISBN检索书籍详细信息

时间:2013-10-01 15:14:43

标签: .net amazon-web-services amazon-product-api isbn

我希望通过从VB.NET程序发送包含书籍ISBN号的(概念上)简单请求,从Amazon Web Services(AWS)产品广告API检索书籍详细信息(以XML格式)。我有一个带有AWS Access Key和Secret密钥的Amazon AWS账户。

我可以进入访问AWS的阶段,但得到以下响应:

  <?xml version="1.0"?>
  <ItemLookupErrorResponse xmlns="http://ecs.amazonaws.com/doc/2005-10-05/">
  <Error><Code>SignatureDoesNotMatch</Code><Message>The request signature we calculated does not
  match the signature you provided. Check your AWS Secret Access Key and signing method. Consult
  the >service documentation for details.</Message></Error>
  <RequestId>556dafef-b59f-4829-8ffe-80668cea9707</RequestId>
  </ItemLookupErrorResponse>

我使用的代码如下(这里真正的Access密钥和密钥已被虚拟字符串替换):

Public Shared Function MakeRequestString(IsbnString As String) As String

    Dim stringToSign, strTimestamp, strSignature, strSignedRequest, strParamValuePairs As String

    stringToSign = "GET" & vbLf   'vbLf is Line feed character Ascii 10

    stringToSign &= "webservices.amazon.com" & vbLf

    stringToSign &= "/onca/xml" & vbLf

    '-----------------------------------------------------------------------

    strParamValuePairs = "AWSAccessKeyId=" & GetAWSAccessKey()

    strParamValuePairs &= "&IdType=ISBN"

    strParamValuePairs &= "&ItemId=" & IsbnString

    strParamValuePairs &= "&Operation=ItemLookup"

    strParamValuePairs &= "&Service=AWSECommerceService"

    strTimestamp = DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ss.fff")

    strParamValuePairs &= "&Timestamp=" & UrlEncode(strTimestamp)

    stringToSign = stringToSign & strParamValuePairs

    '---------------------------------------------------------------
    strSignature = MakeSignature(stringToSign)
   '----------------------------------------------------

    strSignedRequest = "http://webservices.amazon.com/onca/xml?"

    strSignedRequest &= "AWSAccessKeyId=" & GetAWSAccessKey()

    strSignedRequest &= "&IdType=ISBN"

    strSignedRequest &= "&ItemId=" & IsbnString

    strSignedRequest &= "&Operation=ItemLookup"

    strSignedRequest &= "&Service=AWSECommerceService"

    strSignedRequest &= "&Signature=" & UrlEncode(strSignature)

    strSignedRequest &= "&Timestamp=" & UrlEncode(strTimestamp)

    Return strSignedRequest

End Function


Private Shared Function MakeSignature(ByVal StringToHash As String) As String

    Dim myEncoder As New System.Text.UTF8Encoding

    Dim strSecretAccessKey As String = GetSecretKey()

    Dim Key As Byte() = myEncoder.GetBytes(strSecretAccessKey)

    Dim bytStringToHashAsBytes As Byte() = myEncoder.GetBytes(StringToHash)

    Dim myHMACSHA256 As New System.Security.Cryptography.HMACSHA256(Key)

    Dim HashCode As Byte() = myHMACSHA256.ComputeHash(bytStringToHashAsBytes)

    Return Convert.ToBase64String(HashCode)

End Function


Private Shared Function GetSecretKey() As String

    Return "AAAAAAA Secret Key AAAAAAA"

End Function


Private Shared Function GetAWSAccessKey() As String

    Return "AAAA Access Key AAAAA"

End Function

要汇编上述代码,我已遵循亚马逊AWS产品广告API开发人员指南示例休息请求(http://docs.aws.amazon.com/AWSECommerceService/latest/DG/rest-signature.html

注意,在生成签名后的这些指南(步骤9)中,指令是对签名中的加号(+)和等号(=)进行URL编码,然后在签名请求中包含这样的URL编码签名 - 但是在他们在指南中使用的示例中,他们似乎对URL中的其他字符进行URL编码,例如正斜杠字符。我已尝试过URL编码,但无济于事。

关于URL编码,某些参数不包含任何可能存在问题的字符,这包括AWS Access Key。时间戳包含 - 和:字符,Secret键似乎总是有一个正斜杠(/)字符。计算出的签名中将包含特殊字符。

我注意到如果在时间戳中包含空格,那么请求不会进入返回AWS错误的阶段,而是会发现无法找到网页的错误(因此在日期和时间之间的T时间戳。)

0 个答案:

没有答案