Closed leoliang92 closed 3 years ago
Duplicate of https://github.com/mhart/aws4/issues/113#issuecomment-639291510 and https://github.com/mhart/aws4/issues/121#issuecomment-730849155
Access to requested resource is denied
means that the code was signed correctly, but there are issues with your authentication – so aws4
is working correctly here.
It's most likely an issue with the way you're using the temporary credentials – try using non-temporary credentials and see if that works
Will Postman show you the headers and path it's sending? If so, see if you can determine what's different
Also make sure you've setup your IAM role correctly: https://github.com/amzn/selling-partner-api-docs/commit/d5c43fd770795b66bb56cb5edbf501392fe4ca3d#diff-0688a50a7c1991ab58a48a0333ced82e2a1be0073533a73ca1e89546bfb67f42
Hi @mhart,
Thank you so much for your response. I have looked into amzn/selling-partner-api-models#771 & amzn/selling-partner-api-models#779 for at least 10 times, but everything we did seems matching the solutions provided there. We also double checked our IAM role is setup correctly. Otherwise, I don't think we can even get a response back from the postman.
You mentioned about using non-temporary credentials, and I though you have to use the temporary AccessKeyId, SecretAccessKey and SessionToken returned from the sts assume role method to sign the request for selling partner api? Could you give an example how to get non-temporary credentials and pass them into the request?
This example uses non-temporary credentials: https://github.com/mhart/aws4/issues/113#issuecomment-639291510
If you can show the difference between the headers (and anything else) that Postman is sending, and what you are sending here, then you might be able to see what needs to be changed.
To be honest, I don't think amzn/selling-partner-api-models#771 should work at all. If we directly use non-temporary credentials, it will return the unauthorized error. His solution was more likely based on the old documentation. If you look at the code example here: https://vdanyliv.medium.com/amazon-selling-partner-api-spapi-how-to-quickly-and-simply-integrate-with-new-api-part-2-59d7458f24fe and here: https://github.com/amzn/selling-partner-api-models/issues/690
To get it work on postman, we need to have 3 steps.
Here is a sample request headers from Postman
x-amz-access-token: Atza|IwEBIM8IZFu3v....
Host: sellingpartnerapi-na.amazon.com
X-Amz-Security-Token: FwoGZXIvYXdzEOn//////////wEaD....
X-Amz-Date: 20210201T151715Z
Authorization: AWS4-HMAC-SHA256 Credential=ASIAZF262CB4K3FXXEH4/20210201/us-east-1/execute-api/aws4_request, SignedHeaders=host;x-amz-access-token;x-amz-date;x-amz-security-token, Signature=f99824d135d76d8bd1bab505abdb....
User-Agent: PostmanRuntime/7.26.8
Accept: */*
Postman-Token: c9a8d24a-015e-4db1-8a0....
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Here is the entire signed request we send through node https
{
host: 'sellingpartnerapi-na.amazon.com',
path: '/vendors/orders/v1/purchaseOrders?createdAfter=2021-01-12',
method: 'GET',
service: 'execute-api',
region: 'us-east-1',
headers: {
'user-agent': 'mlabs/0.1 (Language=JavaScript; Platform=Node)',
'x-amz-access-token': 'Atza|IwEBINZYKRi9b...',
Host: 'sellingpartnerapi-na.amazon.com',
'X-Amz-Security-Token': 'FwoGZXIvYXdzEOn//////////wEaDM5Y37fi....',
'X-Amz-Date': '20210201T151726Z',
Authorization: 'AWS4-HMAC-SHA256 Credential=ASIAZF262CB4JUS7YNF5/20210201/us-east-1/execute-api/aws4_request, SignedHeaders=host;x-amz-access-token;x-amz-date;x-amz-security-token, Signature=d3502c1d7347e8670aded8c978....'
}
}
The access key id is different in those two requests – you sure you're using the same credentials?
Also the x-amz-access-token
is different
Try to make all the credentials (accessToken, accessKeyId, secretAccessKey, and sessionToken) all exactly the same between the two methods: Postman and Node.js/aws4
Might be easier just to hardcode the credentials in your JS code to get this to work, ie:
let signedRequest = aws4.sign({
host: 'sellingpartnerapi-na.amazon.com',
path: '/vendors/orders/v1/purchaseOrders?createdAfter=2021-01-12',
method: 'GET',
service: 'execute-api',
region: 'us-east-1',
headers: {
'user-agent': 'mlabs/0.1 (Language=JavaScript; Platform=Node)',
'x-amz-access-token': "MY_ACCESS_TOKEN"
}
}, {
accessKeyId: "MY_ACCESS_KEY_ID",
secretAccessKey: "MY_SECRET_ACCESS_KEY",
sessionToken: "MY_SESSION_TOKEN"
})
@mhart Ok, I've changed them to use the same credentials. Same result. Here are the request headers:
Postman:
x-amz-access-token: Atza|IwEBILJjKIJLOacvUHiBWmVDDPaONR-WAmJdCiphXhnh-5fLi-SRq6Yj8VymFwffXK1QAIGOkQQJftZ0xjUJN1kaOXPTo....
Host: sellingpartnerapi-na.amazon.com
X-Amz-Security-Token: FwoGZXIvYXdzEOn//////////wEaDISg+6c02wF/DG9a8SKqATHqxQtYcoyw2+AE4hhMA5FSp9Tr2vQPX/NXo3QIy1pbKe5QLZRAv846zgWsf4f+nW3KrUyW0vIlq4qyJKZLPGvU7U/wPsBOJbOJKKGP4tbgru7EAbNb2i0XPKuFriJibahJ2URylVshymHZDpELnxDRYBK8fMxMaHl+Ll3ZzcMiHisG4nWY62eJbm/eE...
X-Amz-Date: 20210201T154924Z
Authorization: AWS4-HMAC-SHA256 Credential=ASIAZF262CB4KXO4YYOB/20210201/us-east-1/execute-api/aws4_request, SignedHeaders=host;x-amz-access-token;x-amz-date;x-amz-security-token, Signature=7a79f1742f9bf30af8392edac2327d524050b2355c68...
User-Agent: PostmanRuntime/7.26.8
Accept: */*
Postman-Token: 687401b6-9cd1-47e3-be73-029d8cc46f05
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Node aws4:
{
host: 'sellingpartnerapi-na.amazon.com',
path: '/vendors/orders/v1/purchaseOrders?createdAfter=2021-01-12',
method: 'GET',
service: 'execute-api',
region: 'us-east-1',
headers: {
'user-agent': 'mlabs/0.1 (Language=JavaScript; Platform=Node)',
'x-amz-access-token': 'Atza|IwEBILJjKIJLOacvUHiBWmVDDPaONR-WAmJdCiphXhnh-5fLi-SRq6Yj8VymFwffXK1QAIGOkQQJftZ0xjUJN1kaOXPTomwI7GGnc9ntpYkThn-XL-WdSXhnAwnXzV10U7hO3HT-reVNjgk7QODAtUqo3VV_U19_H....',
Host: 'sellingpartnerapi-na.amazon.com',
'X-Amz-Security-Token': 'FwoGZXIvYXdzEOn//////////wEaDISg+6c02wF/DG9a8SKqATHqxQtYcoyw2+AE4hhMA5FSp9Tr2vQPX/NXo3QIy1pbKe5QLZRAv846zgWsf4f+nW3KrUyW0vIlq4qyJKZLPGvU7U/wPsBOJbOJKKGP4tbgru7EAbNb2i0XPKuFriJibahJ2URylVshymHZDpELnxDRYBK8fMxMaHl+Ll3ZzcMiHisG4nWY62e...',
'X-Amz-Date': '20210201T155358Z',
Authorization: 'AWS4-HMAC-SHA256 Credential=ASIAZF262CB4KXO4YYOB/20210201/us-east-1/execute-api/aws4_request, SignedHeaders=host;x-amz-access-token;x-amz-date;x-amz-security-token, Signature=7e4091417fc8e3c5ad4bf9041559bded0998f56....'
}
}
Michael, you are our only hope now!!!! :( :( :(
Well everything looks ok from a request point of view – the Node.js request has everything the Postman one does, except for a couple of headers. You could try adding the Accept
header and see if that makes a difference.
headers: {
'accept': '*/*',
'user-agent': 'mlabs/0.1 (Language=JavaScript; Platform=Node)',
'x-amz-access-token': "MY_ACCESS_TOKEN"
}
Could also see if Connection: keep-alive
is an issue too.
Can't really think of what else it could be. Again, this library is signing the request correctly (otherwise you'd be getting a signature error), so it could only be something else in the way the request is being made – a connection issue (you're not using a proxy?) or an https issue
Ok, I've changed the the headers to include accept and connection, but same result.
Since you mentioned the request result. If I use other library to send the request, such as node-fetch, request, or axios, I will actually get a signature error as follows:
{
"errors": [
{
"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.
The Canonical String for this request should have been
'GET
/vendor/orders/v1/purchaseOrders
createdAfter=2020-01-12
host:sellingpartnerapi-na.amazon.com
x-amz-access-token:Atza|IwEBIDvJFVhcwXRBco_cUjGP6X9VucwBpioq1FvHqI9X9LGVIQ9OoLaSzsVj7RsP0aXeAmd7WVmbNcRXolSSmGLbEz2_lpDvCdBeiBsmUOUV2QlEpAH5WITqitgsGRGQ90doKrWFNpF1tyduExzrilfI6WTfunShtzD-q9BVpVJLBUtquR81UhnFqHXLrm.....
x-amz-date:20210201T161938Z
x-amz-security-token:FwoGZXIvYXdzEOr//////////wEaDMDWahvQputexrSP0CKqAUgaw2tKwL5TKSQzc1rZtGClMHh4QACvzwftDi2stJsBBzHSjUsoaHlZPCX4O6n3d1pWmCkl8n1IEBY0Bq7Qv4lBVSwtQm1....
host;x-amz-access-token;x-amz-date;x-amz-security-token
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b....'
The String-to-Sign should have been
'AWS4-HMAC-SHA256
20210201T161938Z
20210201/us-east-1/execute-api/aws4_request
330f94161763d01e601b461db7ffc1b04a7e1e51c18babc553....'
",
"code": "InvalidSignature"
}
]
}
The request headers from node aws4
{
host: 'sellingpartnerapi-na.amazon.com',
path: '/vendors/orders/v1/purchaseOrders?createdAfter=2021-01-12',
method: 'GET',
service: 'execute-api',
region: 'us-east-1',
headers: {
'user-agent': 'mlabs/0.1 (Language=JavaScript; Platform=Node)',
'x-amz-access-token': 'Atza|IwEBIDvJFVhcwXRBco_cUjGP6X9VucwBpioq1FvHqI9X9LGVIQ9OoLaSzsVj7RsP0aXeAmd7WVmbNcRXolSSmGLbEz2_lpDvCdBeiBsmUOUV2QlEpAH5WITqitgsGRGQ90doKrWFNpF1tyduExzrilfI6WTfunShtzD-q9BVpVJLBUtquR81UhnFqHXLrmaXeclVfemJ7dii0Yu...',
Host: 'sellingpartnerapi-na.amazon.com',
'X-Amz-Security-Token': 'FwoGZXIvYXdzEOr//////////wEaDMDWahvQputexrSP0CKqAUgaw2tKwL5TKSQzc1rZtGClMHh4QACvzwftDi2stJsBBzHSjUsoaHlZPCX4O6n3d1pWmCkl8n1IEBY0Bq7Qv4lBVSwtQm14vVBBjhZ2rffcJRF...',
'X-Amz-Date': '20210201T161938Z',
Authorization: 'AWS4-HMAC-SHA256 Credential=ASIAZF262CB4HTMS6VXT/20210201/us-east-1/execute-api/aws4_request, SignedHeaders=host;x-amz-access-token;x-amz-date;x-amz-security-token, Signature=17756f970413ecfac3490a326c429953ad880c5eabf....'
}
}
This is the code to make the fetch request:
const fetch = require('node-fetch')
let fetchResponse = await fetch('https://sellingpartnerapi-na.amazon.com/vendor/orders/v1/purchaseOrders?createdAfter=2020-01-12',
{
method: 'GET',
headers: signedRequest.headers
}).then(res => res.text())
Hi guys, we also posted this question under Amazon selling partner api doc repository, but did not get a solution. Here is the link: https://github.com/amzn/selling-partner-api-models/issues/998 It seems out code is fine, but not sure if we did something wrong when we tried to sign the request. We decided to ask it agin here. Hopefully someone can help us out on this issue. Thank you!!
We have decided to implement our own solution to call SP-API. After going through all the documentation and cases we could find for the past five days, we still cannot get a successful response back. We have set up everything it should be and tested with Postman without any issue, but we just simply cannot get it working in our code. Here is the error we got:
Code we wrote:
Here is the sample response from role request:
Sample response from signedRequest:
If we pasted the accessToken, accessKeyId, secretAccessKey, and sessionToken into Postman, we get a successful response back. Any help will be appreciated! We really need help to get this working....Thank you!!