Проблемы с подписанием API рекламы продуктов Amazon

Я пытаюсь выполнить поиск в базе данных продуктов Amazon со следующим кодом, размещенным на странице примеров кодов веб-сервиса Amazon.

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;
}

и получаю следующую ошибку

Запрос должен содержать параметр Signature.

и в документации Amazon неясно, как подписывать запросы.

любая идея, как заставить его работать???

Спасибо


person Mahes    schedule 26.04.2011    source источник
comment
ознакомьтесь с документацией здесь: docs.amazonwebservices.com/AWSECommerceService/ 01.11.2010/ГД/   -  person Denise    schedule 26.04.2011
comment
а также пример кода: aws.amazon.com/code/Product-Advertising -API/3941   -  person Rup    schedule 26.04.2011


Ответы (3)


Существует вспомогательный класс для REST, который называется SignedRequestHelper.

Вы называете это так:

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

В приведенных выше ссылках должен быть аналогичный для вызовов SOAP.

person BurnWithLife    schedule 26.04.2011
comment
Кто-нибудь может сказать мне, где я могу получить этот класс SignedRequestHelper? В С#... - person Liran Friedman; 19.12.2016

я расшифровал это vb код и у меня работает

добавьте ссылку на сервис и назовите его Amazon

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

перейдите в папку, в которой размещен ваш проект, откройте папку ссылки на службу и откройте Reference.cs, затем замените все вхождения [][] на [], затем откройте AWSECommerceService.wsdl и найдите

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

и заменить на

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

добавьте следующее, и вам нужно будет вручную ссылаться на некоторые 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

первые различные реализации интерфейса

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

теперь вы используете сгенерированный код таким образом

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);
person GroThar    schedule 07.12.2013

попробуйте это.. надеюсь, это поможет.. я пытаюсь, и это работает.. пожалуйста, поделитесь им с другими.

загрузите пример кода на http://www.falconwebtech.com/post/Using-WCF-and-SOAP-to-Send-Amazon-Product-Advertising-API-Signed-Requests

нам нужно обновить ссылки на службы, внести небольшие изменения в app.config, program.cs и reference.cs.

app.config: (1.) тег appSettings; назначьте значения accessKeyId и secretKey, добавьте . (2.) тег поведения -> тег endpointBehaviors -> тег поведения -> тег signingBehavior; назначьте значение accessKeyId и secretKey. (3.) тег привязки -> тег basicHttpBinding; (необязательно) удалите тег привязки, кроме AWSECommerceServiceBindingNoTransport и AWSECommerceServiceBindingTransport. (4.) тег клиента; удалить тег конечной точки, кроме AWSECommerceServiceBindingTransport.

program.cs: добавить itemSearch.AssociateTag = ConfigurationManager.AppSettings["associateTag"]; перед ответом ItemSearchResponse = amazonClient.ItemSearch(itemSearch);

reference.cs: (открыть файл в папке ссылок на сервисы с помощью Visual Studio) изменить private ImageSet[][] imageSetsField; в частный ImageSet[] imageSetsField; изменить общедоступный набор изображений [][] ImageSets {...} на общедоступный набор изображений [] ImageSets {...}

наконец, мы можем запустить нашу программу, и она заработает. удачи..

NB: будет 1 предупреждение (недопустимое поведение подписи дочернего элемента), я думаю, мы можем его проигнорировать, или, если у вас есть какое-либо решение, поделитесь им.. ^^v..

person ardyfajarai    schedule 24.05.2012