Amazon Product Advertising API Signing Issues

不羁岁月 提交于 2019-12-01 22:02:33

There's a helper class for REST called SignedRequestHelper.

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.

i transcribed this vb code and it works for me

add the service reference and name it 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

<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

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);
ardyfajarai

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

we need to update service references, make little change at app.config, program.cs, and reference.cs.

app.config: (1.) appSettings tag; assign accessKeyId and secretKey value, add . (2.) behaviours tag -> endpointBehaviors tag -> behaviour tag -> signingBehavior tag; assign accessKeyId and secretKey value. (3.) bindings tag -> basicHttpBinding tag; (optional) delete binding tag except AWSECommerceServiceBindingNoTransport and AWSECommerceServiceBindingTransport. (4.) client tag; delete endpoint tag except AWSECommerceServiceBindingTransport.

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

reference.cs: (open file in service references folder using visual studio) change private ImageSet[][] imageSetsField; to private ImageSet[] imageSetsField; change public ImageSet[][] ImageSets {...} to 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..

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!