I am using CreatePolicy API to create a policy with specific permissions. Initially passed json code as a value to query string parameter "PolicyDocument" but the request failed with code 400 Bad request. While testing through postman found that we have to urlencode given policy document. This solution worked fine on postman but not on my HTTP Client. Error - "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". Code is working fine for all other APIs even for IAM Get request, but failing when policy doc is being sent as a query string or as a body. Possibly there is something wrong while calculating the signature for IAM api with url encoded policy doc.
Ref - https://docs.aws.amazon.com/IAM/latest/APIReference/API_CreatePolicy.html
Tried passing policy doc as a request body and header - "Content-Type:application/x-www-form-urlencoded". (body is JSON converted to string)
Tried passing policy doc as a query parameter which is url-encoded
Note - Both these methods worked fine when testing them through postman
I try to send request to AWS with signature using AWS Signature v4 Implementation for Web Browsers.
My request look like:
GET /test?id=ID-12
I get the 403 error with message like:
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
/test
accept:*/*
...
so, as you see, here no param, which I think the issue, but what I don't understand, how AWS can make a suggestion about what should have been? I mean signature is represent by hash, no? Or I'm missing something? Thanks in advance!
Simplifying the process a bit, AWS uses HMAC to generate the signature.
One of the key principles is that HMAC does not encrypt the message. The message must be sent alongside the HMAC hash. The receiving side will calculate the HMAC again and verify the results.
AWS explicitly talks a bit about this in the Signature Documentation:
When an AWS service receives the request, it performs the same steps that you did to calculate the signature you sent in your request. AWS then compares its calculated signature to the one you sent with the request. If the signatures match, the request is processed. If the signatures don't match, the request is denied.
To answer your explicit question: The string they're showing you that they used to generate the "Canonical String" is derived from the HTTP request itself. The HTTP type as "GET" in the first line, the path passed to GET on the second line, and so on.
In other words, they're expecting the caller to understand what the request will look like, generate the Canonical String themselves beforehand, run their signature algorithm on it and the shared secret of the Access Key's Secret, and include the resulting hash in the request. Then on their side they take elements from the HTTP request, run this process again, and verify the result is correct.
For your failure, if you post how you're generating the presigned URL, we might be able to diagnose where the failure is.
I am IAM user and trying to hit API RekognitionService.CreateCOllection for the testing in POSTMAN, but getting this
<InvalidSignatureException>
<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>
</InvalidSignatureException>
My header request is
https://rekognition.us-east-2.amazonaws.com/
Content-Type:application/x-www-form-urlencoded
Host:rekognition.us-east-2.amazonaws.com
Accept-Encoding:identity
X-Amz-Target:RekognitionService.CreateCollections
Content-Length:30
Authorization:AWS4-HMAC-SHA256 Credential=AKIAJCWZHWIIW7BH5HPA/20180202/us-east-2/rekognition/aws4_request, SignedHeaders=accept-encoding;content-length;content-type;host;x-amz-date;x-amz-target, Signature=847d47d4e323fed46020c9fb2ac32882a01edd6efa179ed241d36d038712469e
X-Amz-Date:20180202T121035Z
Content-Type:application/x-www-form-urlencoded
Though it works with same Access Key Id and Secret Key using CLI(Command Line Interface).
Can anyone help me to solve this problem.
First clear all your headers that you have manually added.
Use your Accesskey,SecretKey and service name as rekognition in AWS singature
Add your collectionId in body as raw type.
After updating your request header look like this
Add new header X-Amz-Target value as RekognitionService.CreateCollection and Content-Type as application/x-amz-json-1.1
I have created an API Key and added it to my functions. I have then deployed the api and tested it but still get:
"message": "Forbidden"
How do I pass the api key with my JSON request as I have been using "x-api-key": "theKey"?
The x-api-key parameter is passed as a HTTP header parameter (i.e. it is not added to the JSON body). How you pass HTTP headers depend on the HTTP client you use.
For example, if you use curl and assuming that you POST the JSON payload, a request would look something like (where you replace [api-id] with the actual id and [region] with the AWS region of your API):
$ curl -X POST -H "x-api-key: theKey" -H "Content-Type: application/json" -d '{"key":"val"}' https://[api-id].execute-api.[region].amazonaws.com
I had to add an API Usage plan, and then link the plan to the API stage.
Seems like this is the only way to link the key to the API, not sure if this is a recent change on AWS.
If you set 'API Key Required' option to true, please check below.
you have to pass 'x-api-key' HTTP Header Parameter to API Gateway.
The API Key had to be created.
In addition, you need to check a Usage Plan for the API Key on API Gateway Console.
If you set 'API' key required to true, you need to pass the api key as header.
API Key is passed as header field 'x-api-key'. Even after adding this field in header, this issue may occur. In that case, please validate below points
Do you have a Usage Plan? if not need to create one.
Link you API with Usage Plan. For that add a stage, it will link your API
Do you have API Key? if not you need to create an API Key and enable it.
Add the Usage Plan which is linked with your API to this API Key. For that, add Usage Plan.
I hope you are not missing to link the API key with the API
I was able to get a successful response from Lambda using below configuration in Postman native app -
Under authorization tab (For some reason this didn't work when i passed the same parameters under header)
Key : x-api-key
Value : your-api-key-value
Add to : Header
I don't have enough reputation to set this as a comment, But I was finally able to find the document specifying that 'x-api-key' belongs in the header for API Gateway calls that come from outside clients (like postman, swagger, etc.) in the AWS Documentation.
The relevant part:
To use header-sourced API keys:
Create an API with desired API methods. And deploy the API to a
stage.
Create a new usage plan or choose an existing one. Add the deployed
API stage to the usage plan. Attach an API key to the usage plan or
choose an existing API key in the plan. Note the chosen API key
value.
Set up API methods to require an API key.
Redeploy the API to the same stage. If you deploy the API to a new
stage, make sure to update the usage plan to attach the new API
stage.
The client can now call the API methods while supplying the x-api-key
header with the chosen API key as the header value.
Choose an API key source
For Private API Gateways accessed through public DNS, we need to pass additional header of 'x-apigw-api-id' with the api id along with 'x-api-key' if configured.
curl -v https://{vpce-id}.execute-api.{region}.vpce.amazonaws.com/test -H 'x-apigw-api-id:{api-id}'
Its documented below,
https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-private-api-test-invoke-url.html#w20aac13c16c28c11
Here a good resource explaining different reasons why we could be getting a Forbidden. The two most important are the request URL and the x-api-key header:
https://{api_id}.execute-api.{region}.amazonaws.com/{stage_name}/{resource_name}
Missing stage name will give you 403 for ex. Maybe for security reasons the response is not revealing an issue with the stage name, and thus you get a generic Forbidden.
I faced the same problem today. I had already mapped the API key to the usage plan (which was linked to the api gateway stage). I was also passing the api key in header correctly.
When none of these solutions work, do remember to check if your API is linked to WAF policy with only a certain ip-addresses permitted. Apparently, my IP address had changed today. So, WAF was blocking me. That can be an additional reason to get {"message": "Forbidden"} error.
Documentation here:
http://docs.amazonwebservices.com/AlexaWebInfoService/latest/
http://awis.amazonaws.com/?
Action=UrlInfo
&AWSAccessKeyId=[Your AWS Access Key ID]
&Signature=[signature calculated from request]
&SignatureMethod=[HmacSha1 or HmacSha256]
&SignatureVersion=2
&Timestamp=[timestamp used in signature]
&Url=[Valid URL]
&ResponseGroup=[Valid Response Group]
I don't understand this...
&Signature=[signature calculated from request]
&SignatureMethod=[HmacSha1 or HmacSha256]
How do you calculate the signature?
&AWSAccessKeyId=[Your AWS Access Key ID]
This does not work as well! There's no AWS secret key required here here, but it simple doesn't recognize the Access Key ID, in my account.
AWS was not able to authenticate the request: access credentials are missing
I can't do something as simple as:
http://awis.amazonaws.com/?Action=UrlInfo&AWSAccessKeyId=AKIAISCXZCPDLPUDDAVA&SignatureVersion=2&Url=http://www.google.com&ResponseGroup=TrafficData
Have you checked following things, its given in Documentation Under Authentication Errors Section:
If you get an authentication error then one of the following is probably true:
You are not signed up for the Alexa Web Information service. Even if you already have an Amazon Web Services account, you must separately sign up for the Alexa Web Information service at Amazon AWS.
Your credit card is invalid or expired.
You have not URL encoded your Timestamp and Signature values.
If you are seeing intermittent authorization errors, this is the most
likely problem. You should not see any "+" signs in your Signature, for example.
You are not generating the Signature correctly. Please see the code samples.
The clock on the computer making the requests is not set correctly.