API Gateway configuration returns 403 - amazon-web-services

I have an API Gateway configured and deployed. If I make a GET request to one of its staged endpoints, for example https://1234567890.execute-api.us-east-1.amazonaws.com/dev/doc, I get a 200 OK response.
If I take a look at the Custom Domain Names section and supplant the URL found there into my request, for example abcdefghijkl-f4cwy0d1u5.execute-api.us-east-1.amazonaws.com to make https://abcdefghijkl-f4cwy0d1u5.execute-api.us-east-1.amazonaws.com/dev/doc, I get 403 Forbidden.
Am I wrong in thinking that I should be able to make a request to the domain name - and thus use the API's Custom domain name in a CNAME record - or does the 403 indicate that a specific configuration item is missing?

you can find some response headers that come together with your 403 error here: https://aws.amazon.com/premiumsupport/knowledge-center/api-gateway-troubleshoot-403-forbidden/
this might help you to find which error you are facing!

TL;DR: When getting 403 Forbidden with API Gateway and using the Custom domain name it's important to trim the stage name because API Gateway is routing the custom name to that stage.
Using the documentation provided by #leoandreotti I was able to identify the response header:
x-amzn-ErrorType: ForbiddenException
For this, the documentation states:
Invoking a REST API that has a custom domain name using the default
execute-api endpoint - The caller uses the default execute-api
endpoint to invoke a REST API after disabling the default endpoint.
This made me think back to a header I had been recommended to use by a colleague - the Host header.
So, I added the header back into the request and got this:
x-amzn-ErrorType: MissingAuthenticationTokenException
For which the docs state:
Resource path doesn't exist - A request with no "Authorization" header
is sent to an API resource path that doesn't exist.
But the path /dev/doc absolutely does exist. Then I realised that the /dev portion is actually the stage name.
So I trimmed the /dev portion from the path and got 200 OK - then I removed the Host header and also got 200 OK!
Thanks #leoandreotti

Related

AWS API Gateway expects the request URL to be encoded twice

My API is a request that can potentially have spaces in the pathParameters.
/data/{id}/hello/{Some message with a space}.
A sample request would be /data/23/hello/Say%20Hi
My angular code from the frontend encodes the request URL that is sent out to the AWS API Gateway but I get the following error.
`The Canonical String for this request should have been
'GET
/data/23/hello/Sayr%2520Hi`
My API gateway has a velocity template the decodes the parameters using $util.urlDecode()
I'm facing the same problem.
I've been stuck for a day.
If you are using HttpApi it cannot be solved.
Nevertheless, if you use RestApi I managed to make this work.
Specifically, you should use the URL Path Parameters.
You should:
Add a resource containing the /{variable}
Add a Url Path Parameter in the Integration Request Configuration with name variable and mapped from method.request.path.variable
Notice that the solution may depend on the integration type that you are using.
In the screenshot below you can see how I'm redirecting all the received traffic to a NetworkLoadBalancer.
The resource has the variable /{proxy+}, the endpoint URL has the {proxy}, and, in the URL Path Parameters, I've configured the mapping method.request.path.proxy.

why does api gateway with http api using api mapping fail with 404?

I have a custom domain name in AWS API gateway. I am using the same domain for 2 separate API stages. One API stage is REST API, and the other HTTP API.
When I test out my setup, everything works for the REST API. However, the mapping path for HTTP API is not working and I get status-code = 404 Not Found, with 0kb body.
references used:
https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-mappings.html
https://docs.aws.amazon.com/apigateway/latest/developerguide/rest-api-mappings.html
From my testing in postman, i get the following result when calling the custom domain.
1. {{api.gateway.custom.domain.url}}/foobar - works
2. {{api.gateway.custom.domain.url}}/this-no-work/foobar - 404
3. {{api.gateway.custom.domain.url}}/this-works/foobar - works
does anyone know why (2) gives 404? api-gateway REST API with mapping works while api-gateway HTTP API will return 404 with 0kb body. Is there something I am missing?
note: the (none) path mapping has been added for a sanity check, and I was able to get the expected response.
I had the same problem.
The problem is in the configuration of routers of your application.
When you configure one API mapping in AWS API Gateway, the configured path (this-no-work) is passed to your web application as a prefix of routes.
SO ... if you have one route like this:
/api/foobar
you need configure one more route with the prefix point to the same action:
/this-no-work/api/foobar
A good one is to make one global configuration to your web app.
You can note it enabling the cloudwatch logs of your API Gateway stage and looking into the cloudwatch logs the path property passed from API Gateway to the Web application.
Thanks to answer from #gean-ribeiro, I was able to figure why my HTTP API was returning 404 Not Found.
Turns out it was not an issue with HTTP API. The error 404 Not Found with 0kb body was coming from the API integration sitting behind APIG. Specifically, it was a load balancer using rules based on HTTP path pattern.
By default, any unmatched path pattern will return 404 with text/plain body. this-no-work was a new HTTP API I added, and it did not have the necessary listener rules.
Once I added a new listener rule for HTTP Path pattern is /this-no-work/*, it worked as expected..
when default endpoin is created in my case it uses this pattern
https://{api_id}.execute-api.{region}.amazonaws.com/
an answer might be: Disable the default endpoint for an HTTP API
more details here
https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-disable-default-endpoint.html

AWS API Gateway 403 Forbidden response OPTIONS

I am trying to call API of AWS through JEE and I got this error in the Chrome Console
[![enter image description here][1]][1]
But when I call same API from postman or when I use it in localhost it works.
Whats wrong ?
In your API Gateway OPTIONS method, go into Method Response and add a response header with the name 'Access-Control-Allow-Origin'.
Now go into Integration Response, expand the default 200 response and in Header Mappings put the URL of your DNS. If you don't want to restrict by URL, just put a *.
You may need to add this configuration to other methods as well.

API Gateway POST request returns "error http://localhost:3000 is not allowed by Access-Control-Allow-Origin”

So I'm trying to write a POST method that triggers a lambda function which will in turn write to a DynamoDB database. The logic behind all of that seems fine, and I can invoke the lambda function when I make a POST request to the API through POSTMAN. However, when I try to do the same from my actual application, which doesn't currently have a domain, I get the error:
Type error: Origin http://localhost:3000 is not allowed by
Access-Control-Allow-Origin
Since I don't have a domain I am developing using localhost:3000. Can I get this to work with API Gateway? I already have CORS setup with [*] as my list of domains, so this should be open to every domain.
Try to
change localhost to "lvh.me" which points to 127.0.0.1
or
edit your hosts file so that local.[mysite].com points to 127.0.0.1, then make your CORS file allow *.[mysite].com
check:
stack

API Gateway CORS HTTP 415

Okay, I've been all over these interwebs looking for some insight to my issue; I've probably been through over 80 stack overflow threads RE api gateway and such, but none of them seem to help or speak close enough to my issue.
I'm new to API Gateway and cors, but lets see if i can articulate the issue that i am seeing:
Setting up a API gateway proxy to Kinesis firehose hydrating a redshift database. The proxy, firehose, and redshift gateway are up and working when called in isolation, but when called from one of our customer sites, we get an error as follows:
XMLHttpRequest cannot load [api_call_here]. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin [origin_website_here] is therefore not allowed access. The response had HTTP status code 403.
Okay, so that strongly implies that CORS is needed, right? in the console on the resource, enable cors, deploy, new error:
XMLHttpRequest cannot load [api_call_here]. Request header field $cookies is not allowed by Access-Control-Allow-Headers in preflight response.
Ooooooooookay, from the new OPTIONS method added by the enable CORS feature, in integration response, allowed headers, under access control allowed headers add '$Cookies', deploy.
Now i get a new error, very similar to the first error:
XMLHttpRequest cannot load [api_call_here]. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin [origin_website_here] is therefore not allowed access. The response had HTTP status code 415.
Notice the first error had HTTP status code 403, and this third one has status code 415. This is where I'm having issues. If I go into the GET method acting as the proxy method, body mapping templates, I have "When there are no templates defined (recommended)" selected.
Now, I read that when API gateway fails to find a matching template it rejects with a 415 error, so I changed aforementioned option to "When no template matches the request Content-Type header". That made the error disappear, but the data is still not being persisted to redshift when called from the origin. Again, when I call the api directly from postman, insomnia or just a plain old address bar, the records are added nicely.
Opening up chrome and looking at the header i see that the cookie is coming across as text/html.
Regarding the template mapping up there, i have only defined a map for application/json; could that be part of the problem?
Also, the response header as viewed from chrome's console is as follows:
content-length:37
content-type:application/json
date:Wed, 19 Apr 2017 23:43:35 GMT
status:415
via:1.1 [blahblabbleblah].cloudfront.net (CloudFront)
x-amz-cf-id:[blahblabbleblah]
x-amzn-requestid:[blahblabbleblah]
x-cache:Error from cloudfront
I'm relatively new to this so i dont see how cloudfront fits in with this, especially give that it is complaining about media type while the console is complaining about no access-control-allow-origin header.
At any rate, any help as to how to resolve the third error would be most appreciated.
What is the content-type in your requests from the browser? If content-type header isn't specified in the request, then API Gateway assumes "application/json" by default.
Opening up chrome and looking at the header i see that the cookie is coming across as text/html.
I am not sure if you meant that "Content-type" header's value in the request is set to "text/html". If yes, that's the problem. You will either need a matching template, or you will need to pass through by default by choosing "When no template matches the request Content-Type header".
I have some issue with AWS API GW with SQS integration. Problem was that incorrect content type in mapping template, I wrote application/json but correct is application/x-www-form-urlencoded
The request body will never be passed through to the integration.
Requests with a Content-Type header that don't match any templates
will be rejected with a HTTP 415 response.