I am using the aws-sigv4 gem for creating the signature and I am getting the error

1k Views Asked by At
require 'aws-sigv4'

signer = Aws::Sigv4::Signer.new(access_key_id: access_key, region: 'us-east-1',secret_access_key: secret_key,service: 'execute-api')

signature = signer.sign_request(
  http_method: 'GET',
  url: 'https://sandbox.sellingpartnerapi-na.amazon.com/feeds/2021-06-30/feeds',
  headers: {
    'host' => 'sellingpartnerapi-na.amazon.com',
    'user_agent' => 'test (Language=Ruby)',
    'x-amz-access-token' => access_token
  })

 response = HTTParty.send(:get, 'https://sandbox.sellingpartnerapi-na.amazon.com/feeds/2021-06-30/feeds', headers: {
  'host' => signature.headers['host'],
  'user_agent' => 'test (Language=Ruby)',
  'x-amz-access-token' => access_token,
  'x-amz-content-sha256' => signature.headers['x-amz-content-sha256'],
  'x-amz-date' => signature.headers['x-amz-date'],
  'Authorization' => signature.headers['authorization'],
})

I am getting the following error

#<HTTParty::Response:0x55a044ec7c98 parsed_response={"errors"=>[{"message"=>"Access to requested resource is denied.", "code"=>"Unauthorized", "details"=>"Access token is missing in the request header."}]}, @response=#<Net::HTTPForbidden 403 Forbidden readbody=true>, @headers={"date"=>["Mon, 12 Jul 2021 09:16:40 GMT"], "content-type"=>["application/json"], "content-length"=>["187"], "connection"=>["close"], "x-amzn-requestid"=>["db0c65ea-f15a-4532-aadb-532b0eb1c6f2"], "x-amzn-errortype"=>["AccessDeniedException"], "x-amz-apigw-id"=>["CWZCzHploAMF6oA="]}>

When I tried to hit the request using the postman with the signature which I have generate above I am getting the following error

{
    "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.\n\nThe Canonical String for this request should have been\n'GET\n/feeds/2021-06-30/feeds\n\ncontent-type:\nhost:sandbox.sellingpartnerapi-na.amazon.com\nx-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\nx-amz-date:20210712T140633Z\n\ncontent-type;host;x-amz-content-sha256;x-amz-date\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'\n\nThe String-to-Sign should have been\n'AWS4-HMAC-SHA256\n20210712T140633Z\n20210712/us-east-1/execute-api/aws4_request\n5c4a3c5b6bfb8d42b8f45993ff0ba1fa49d82b1b182e6da616bd6ae5f7e98ffd'\n",
            "code": "InvalidSignature"
        }
    ]
}

Here is the screenshot or that https://prnt.sc/1al04od

Can anyone help me with this

1

There are 1 best solutions below

0
On

Sorry this is a bit of a necro-post, but I think you (and anyone else stumbling across this post like myself) deserve an answer.


So a couple of things:

First: regarding your initial error with your Ruby code, my guess is that you're running into a common problem wherein Ruby's Net::HTTPHeader (which HTTParty and other gems utilize) enforces capitalization of headers.

The Selling Partner API enforces the specific casing of x-amz-access-token. Because the Net::HTTPHeader class capitalizes all headers, the ultimate request is actually sending something like X-Amz-Access-Token, and therefore you're seeing an "Access token is missing" error from the API.

See: https://github.com/amzn/selling-partner-api-docs/issues/292#issuecomment-759904882 for more details and a possible workaround.

Second: I don't think you can just copy signed request headers and try to reuse them. You'll want to use Postman's AWS Signature Authorization type when building your request.