ich möchte über die Amazon MWS API Schnittstelle sämtliche Daten (bspw. Orders) abrufen. Leider bekomme ich jedoch jedesmal diese Fehlermeldung:
<?xml version="1.0"?>
<ErrorResponse xmlns="https://mws.amazonservices.com/Orders/2013-09-01">
<Error>
<Type>Sender</Type>
<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>9f03f5b0-e4e4-4766-a554-00ff970b6b8c</RequestID>
</ErrorResponse>
Das wunder mich, da ich die selbe Signatur errechne, wie auch auf dem Amazon Scratchpad (https://mws.amazonservices.de/scratchpad/index.html) berechnet wird (Jedoch nur wenn ich den selben Zeitstempel eintrage, wie auch online generiert wird).
Folgend meine Methode und auch die Funktion zum errechnen der Signatur. Ich komme gerade nicht weiter und hoffe einer von euch weis woran es liegt.
Könnte es sein, dass es am RestCLient liegt? Dieser fügt standartmäßig noch 1-2 weitere Parameter hinzu?
public async void FetchOrders()
{
RestClient client = new RestClient("https://mws.amazonservices.de");
client.DefaultParameters.Clear();
client.ClearHandlers();
Dictionary<string, string> parameters = new Dictionary<string, string>();
parameters.Add("AWSAccessKeyId", "xxxxxxxxxx");
parameters.Add("Action", "ListOrders");
parameters.Add("CreatedAfter", "2018-01-01T11:34:00Z");
parameters.Add("MarketplaceId.Id.1", "A1PA6795UKMFR9");
parameters.Add("SellerId", "xxxxxxxxx");
parameters.Add("SignatureVersion", "2");
parameters.Add("Timestamp", DateTime.UtcNow.ToString("s") + "Z");
parameters.Add("Version", "2013-09-01");
RestRequest request = new RestRequest("Orders/2013-09-01/", Method.POST);
string signature = AmzLibrary.SignParameters(parameters, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
request.AddParameter("Signature", signature);
foreach (KeyValuePair<string, string> keyValuePair in parameters)
{
request.AddParameter(keyValuePair.Key, keyValuePair.Value);
}
IRestResponse result = await client.ExecuteTaskAsync(request);
}
public static class AmzLibrary
{
public static string GetParametersAsString(IDictionary<String, String> parameters)
{
StringBuilder data = new StringBuilder();
foreach (String key in (IEnumerable<String>)parameters.Keys)
{
String value = parameters[key];
if (value != null)
{
data.Append(key);
data.Append('=');
data.Append(UrlEncode(value, false));
data.Append('&');
}
}
String result = data.ToString();
return result.Remove(result.Length - 1);
}
public static String SignParameters(IDictionary<String, String> parameters, String key)
{
String signatureVersion = parameters["SignatureVersion"];
KeyedHashAlgorithm algorithm = new HMACSHA1();
String stringToSign = null;
if ("2".Equals(signatureVersion))
{
String signatureMethod = "HmacSHA256";
algorithm = KeyedHashAlgorithm.Create(signatureMethod.ToUpper());
parameters.Add("SignatureMethod", signatureMethod);
stringToSign = CalculateStringToSignV2(parameters);
}
else
{
throw new Exception("Invalid Signature Version specified");
}
return Sign(stringToSign, key, algorithm);
}
private static String CalculateStringToSignV2(IDictionary<String, String> parameters)
{
StringBuilder data = new StringBuilder();
IDictionary<String, String> sorted =
new SortedDictionary<String, String>(parameters, StringComparer.Ordinal);
data.Append("POST");
data.Append("\n");
Uri endpoint = new Uri("https://mws.amazonservices.de/Orders/2013-09-01");
data.Append(endpoint.Host);
if (endpoint.Port != 443 && endpoint.Port != 80)
{
data.Append(":")
.Append(endpoint.Port);
}
data.Append("\n");
String uri = endpoint.AbsolutePath;
if (uri == null || uri.Length == 0)
{
uri = "/";
}
data.Append(UrlEncode(uri, true));
data.Append("\n");
foreach (KeyValuePair<String, String> pair in sorted)
{
if (pair.Value != null)
{
data.Append(UrlEncode(pair.Key, false));
data.Append("=");
data.Append(UrlEncode(pair.Value, false));
data.Append("&");
}
}
String result = data.ToString();
return result.Remove(result.Length - 1);
}
private static String UrlEncode(String data, bool path)
{
StringBuilder encoded = new StringBuilder();
String unreservedChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~" + (path ? "/" : "");
foreach (char symbol in System.Text.Encoding.UTF8.GetBytes(data))
{
if (unreservedChars.IndexOf(symbol) != -1)
{
encoded.Append(symbol);
}
else
{
encoded.Append("%" + String.Format("{0:X2}", (int)symbol));
}
}
return encoded.ToString();
}
private static String Sign(String data, String key, KeyedHashAlgorithm algorithm)
{
Encoding encoding = new UTF8Encoding();
algorithm.Key = encoding.GetBytes(key);
return Convert.ToBase64String(algorithm.ComputeHash(
encoding.GetBytes(data.ToCharArray())));
}
}