简体   繁体   English

亚马逊产品广告API签名问题

[英]Amazon Product Advertising API Signing Issues

i am trying to search in amazon product database with the following code posted in amazon webservice sample codes page 我正在尝试使用以下代码在亚马逊网络服务示例代码页中搜索亚马逊产品数据库

AWSECommerceService ecs = new AWSECommerceService();

// Create ItemSearch wrapper
ItemSearch search = new ItemSearch();
search.AssociateTag = "ABC";
search.AWSAccessKeyId = "XYZ";

// Create a request object
ItemSearchRequest request = new ItemSearchRequest();

// Fill request object with request parameters
request.ResponseGroup = new string[] { "ItemAttributes" };

// Set SearchIndex and Keywords
request.SearchIndex = "All";
request.Keywords = "The Shawshank Redemption";

// Set the request on the search wrapper
search.Request = new ItemSearchRequest[] { request };

try
{
    //Send the request and store the response
    //in response

    ItemSearchResponse response = ecs.ItemSearch(search);
    gvRes.DataSource = response.Items;
}
catch (Exception ex) 
{
    divContent.InnerText = ex.Message;
}

and getting the following error 并得到以下错误

The request must contain the parameter Signature. 请求必须包含参数Signature。

and amazon documentation is not clear about how to sign the requests. 和amazon文档不清楚如何签署请求。

any idea how to make it work??? 任何想法如何让它工作???

thx 谢谢

i transcribed this vb code and it works for me 我转录了这个 vb代码,它适用于我

add the service reference and name it Amazon 添加服务引用并将其命名为Amazon

http://webservices.amazon.com/AWSECommerceService/AWSECommerceService.wsdl

go into the folder where your project is hosted, open the service reference folder and open the Reference.cs, then replace all the occurrences of [][] with [], next open AWSECommerceService.wsdl and find 进入托管项目的文件夹,打开服务引用文件夹并打开Reference.cs,然后将[] []的所有实例替换为[],然后打开AWSECommerceService.wsdl并查找

<xs:element minOccurs="0" maxOccurs="unbounded" name="ImageSets">

and replace with 并替换为

<xs:element minOccurs="0" maxOccurs="1" name="ImageSets">

add the following, and you'll need to manually reference some dlls 添加以下内容,您需要手动引用一些dll

using System.Security.Cryptography;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Description;
using System.Text.RegularExpressions;
using System.Xml;
using System.IO;
using System.Runtime.Serialization;
using AmazonApiTest.Amazon; //instead of AmazonApiTest use your project name

first various interface implementations 首先是各种接口实现

public class AmazonSigningMessageInspector : IClientMessageInspector
{
    private string accessKeyId = "";
    private string secretKey = "";

    public AmazonSigningMessageInspector(string accessKeyId, string secretKey)
    {
        this.accessKeyId = accessKeyId;
        this.secretKey = secretKey;
    }

    public Object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, IClientChannel channel) 
    {
        string operation = Regex.Match(request.Headers.Action, "[^/]+$").ToString();
        DateTime now = DateTime.UtcNow;
        String timestamp = now.ToString("yyyy-MM-ddTHH:mm:ssZ");
        String signMe = operation + timestamp;
        Byte[] bytesToSign = Encoding.UTF8.GetBytes(signMe);

        Byte[] secretKeyBytes = Encoding.UTF8.GetBytes(secretKey);
        HMAC hmacSha256 = new HMACSHA256(secretKeyBytes);
        Byte[] hashBytes = hmacSha256.ComputeHash(bytesToSign);
        String signature = Convert.ToBase64String(hashBytes);

        request.Headers.Add(new AmazonHeader("AWSAccessKeyId", accessKeyId));
        request.Headers.Add(new AmazonHeader("Timestamp", timestamp));
        request.Headers.Add(new AmazonHeader("Signature", signature));
        return null;
    }

    void IClientMessageInspector.AfterReceiveReply(ref System.ServiceModel.Channels.Message Message, Object correlationState)
    {
    }
}

public class AmazonSigningEndpointBehavior : IEndpointBehavior
{
    private string accessKeyId = "";
    private string secretKey = "";

    public AmazonSigningEndpointBehavior(string accessKeyId, string secretKey)
    {
        this.accessKeyId = accessKeyId;
        this.secretKey = secretKey;
    }

    public void ApplyClientBehavior(ServiceEndpoint serviceEndpoint, ClientRuntime clientRuntime)
    {
        clientRuntime.ClientMessageInspectors.Add(new AmazonSigningMessageInspector(accessKeyId, secretKey));
    }

    public void ApplyDispatchBehavior(ServiceEndpoint serviceEndpoint, EndpointDispatcher endpointDispatched)
    {
    }

    public void Validate(ServiceEndpoint serviceEndpoint)
    {
    }

    public void AddBindingParameters(ServiceEndpoint serviceEndpoint, BindingParameterCollection bindingParemeters)
    {
    }
}

public class AmazonHeader : MessageHeader
{
    private string m_name;
    private string value;

    public AmazonHeader(string name, string value)
    {
        this.m_name = name;
        this.value = value;
    }

    public override string Name
    {
        get { return m_name; }
    }
    public override string Namespace
    {
        get { return "http://security.amazonaws.com/doc/2007-01-01/"; }
    }
    protected override void OnWriteHeaderContents(System.Xml.XmlDictionaryWriter writer, MessageVersion messageVersion)
    {
        writer.WriteString(value);
    }
}

now you use the generated code in this way 现在你以这种方式使用生成的代码

ItemSearch search = new ItemSearch();
search.AssociateTag = "YOUR ASSOCIATE TAG";
search.AWSAccessKeyId = "YOUR AWS ACCESS KEY ID";           
ItemSearchRequest req = new ItemSearchRequest();
req.ResponseGroup = new string[] { "ItemAttributes" };
req.SearchIndex = "Books";
req.Author = "Lansdale";
req.Availability = ItemSearchRequestAvailability.Available;
search.Request = new ItemSearchRequest[]{req};

Amazon.AWSECommerceServicePortTypeClient amzwc = new Amazon.AWSECommerceServicePortTypeClient();
amzwc.ChannelFactory.Endpoint.EndpointBehaviors.Add(new AmazonSigningEndpointBehavior("ACCESS KEY", "SECRET KEY"));

ItemSearchResponse resp = amzwc.ItemSearch(search);

foreach (Item item in resp.Items[0].Item)
     Console.WriteLine(item.ItemAttributes.Author[0] + " - " + item.ItemAttributes.Title);

There's a helper class for REST called SignedRequestHelper. 有一个名为SignedRequestHelper的REST辅助类。

You call it like so: 你这样称呼它:

SignedRequestHelper helper =
        new SignedRequestHelper(MY_AWS_ACCESS_KEY_ID, MY_AWS_SECRET_KEY, DESTINATION);
requestUrl = helper.Sign(querystring);

There must be a similar one for SOAP calls in the above links. 在上面的链接中,SOAP调用必须有类似的一个。

try this one.. i hope it'll help.. i try and it works.. please share it with others. 尝试这个...我希望它会帮助..我尝试它的工作..请与他人分享。

download the sample code on http://www.falconwebtech.com/post/Using-WCF-and-SOAP-to-Send-Amazon-Product-Advertising-API-Signed-Requests 下载http://www.falconwebtech.com/post/Using-WCF-and-SOAP-to-Send-Amazon-Product-Advertising-API-Signed-Requests上的示例代码

we need to update service references, make little change at app.config, program.cs, and reference.cs. 我们需要更新服务引用,在app.config,program.cs和reference.cs上做一点改动。

app.config: (1.) appSettings tag; app.config :( 1.) appSettings标签; assign accessKeyId and secretKey value, add . 分配accessKeyId和secretKey值,添加。 (2.) behaviours tag -> endpointBehaviors tag -> behaviour tag -> signingBehavior tag; (2.)行为标签 - > endpointBehaviors标签 - >行为标签 - > signingBehavior标签; assign accessKeyId and secretKey value. 分配accessKeyId和secretKey值。 (3.) bindings tag -> basicHttpBinding tag; (3.) bindings tag - > basicHttpBinding标签; (optional) delete binding tag except AWSECommerceServiceBindingNoTransport and AWSECommerceServiceBindingTransport. (可选)删除除AWSECommerceServiceBindingNoTransport和AWSECommerceServiceBindingTransport之外的绑定标记。 (4.) client tag; (4.)客户标签; delete endpoint tag except AWSECommerceServiceBindingTransport. 删除除AWSECommerceServiceBindingTransport之外的端点标记。

program.cs: add itemSearch.AssociateTag = ConfigurationManager.AppSettings["associateTag"]; program.cs: add itemSearch.AssociateTag = ConfigurationManager.AppSettings [“associateTag”]; before ItemSearchResponse response = amazonClient.ItemSearch(itemSearch); 在ItemSearchResponse response = amazonClient.ItemSearch(itemSearch)之前;

reference.cs: (open file in service references folder using visual studio) change private ImageSet[][] imageSetsField; reference.cs :(使用visual studio在服务引用文件夹中打开文件) 更改私有ImageSet [] [] imageSetsField; to private ImageSet[] imageSetsField; 私有的ImageSet [] imageSetsField; change public ImageSet[][] ImageSets {...} to public ImageSet[] ImageSets {...} public ImageSet [] [] ImageSets {...}更改为public ImageSet [] ImageSets {...}

finally we can run our program and it will work. 最后我们可以运行我们的程序,它会工作。 good luck.. 祝好运..

nb: there will be 1 warning (invalid child element signing behaviour), i think we can ignore it, or if you have any solution please share.. ^^v.. nb:会有1个警告(无效的子元素签名行为),我想我们可以忽略它,或者如果你有任何解决方案请分享.. ^^ v ..

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM