CloudFront to API Gateway request returns 403: "The request signature we calculated does not match the signature you provided." - aws-api-gateway

I have an API Gateway fronted by CloudFront. The API Gateway has a regional endpoint with api key disabled. An Authorization header must be sent to the regional endpoint or the endpoint returns "Missing Authentication Token" as expected.
Using the same request on the CloudFront endpoint returns the following 403 Forbidden error:
{
"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'POST
// sensitive data here...
}
The Auth token is created from an AWS signature. The signature originates from an IAM role that allows invocation on the endpoint: "Action": "execute-api:Invoke"
Any ideas on why CloudFront isn't able to use these credentials to hit the API Gateway endpoint?
In summary,
"Postman w/ Authorization header -> API Gateway endpoint" works.
"Postman w/ Authorization header -> CloudFront -> API Gateway endpoint" returns the above 403.
UPDATE: Adding information on how I obtain the signature.
IAM Role:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:us-west-2:{ACCOUNT}:{ENDPOINT}",
"Effect": "Allow"
}
]
}
AccessKey, SecretKey, Session Token are obtained in CloudShell:
$ aws sts assume-role --role-arn arn:aws:iam::{ACCOUNT}:{ROLE} --role-session-name {SESSION_NAME}
These 3 keys are then used in Postman's Authorization tab. I select "AWS Signature" type and provide the AccessKey, SecretKey, and SessionToken.
From here, I can hit the API Gateway endpoint and receive 200 response. With the same request and headers, hitting the CloudFront endpoint results in the 403.
UPDATE #2: Adding information on CloudFront configuration.
The distribution behavior for the API GW origin is using the CachingOptimized policy. Its also allowing all HTTP methods.

Related

AppSync request from API Gateway: Valid authorization header not provided

I have an AWS architecture like this:
An API Gateway with many endpoints. One of them is "/graphql"
The "/graphql" API Gateway endpoint points to a "/graphql" AppSync endpoint
My API Gateway uses COGNITO_USER_POOL to authentificate users. When an user makes a request to "/graphql" endpoint of API Gateway, he must to add id_token to "Authorization" header on the request. It works well.
My integration method on API Gateway gets the "Authorization" header and puts it on AppSync request using this HTTP Headers mapping:
Authorization = method.request.header.Authorization
It seems to work correctly also. Nevermind, I got this AppSync error when requesting the API Gateway endpoint:
{
"errors": [
{
"errorType": "UnauthorizedException",
"message": "Valid authorization header not provided."
}
]
}
It doesn't seems to be a token problem, because it works correctly when I request the AppSync endpoint directly (with the same Authorization header).
I observed that API Gateway adds some headers on the AppSync request, to generate a Signature. So my question is: Is there any way to do a request on AppSync from API Gateway without pass the Signature, only the id_token that user got from Cognito User Pool? I'd like to ignore IAM and use only the token (as I do when the request is done directly on AppSync from Postman).
Many thanks!

Azure Data Lake Storage Gen2 REST API - List filesystems - "code": "AuthorizationPermissionMismatch

I try to get list filesystems and their properties in the Azure Storage account using request:
https://<account_name>.dfs.core.windows.net/?resource=account
with one header Bearer
and get response
"error": {
"code": "AuthorizationPermissionMismatch",
"message": "This request is not authorized to perform this operation using this ******"
}
But when I make request for list paths:
https://<account_name>.dfs.core.windows.net/<filesystem>?recursive=true&resource=filesystem
I get a response with correct data.
Can you give me some advice on what is wrong?
P.s. My auth params.
enter image description here
I tested the same request in my environment by getting the token using client ID and secret. I received the same error as you are getting :
As a Solution ,
I added Storage Account Contributor role to the Service Principal
which I am using to get the bearer token as below:
Then , I get the bearer token using below client_credentials method:
After the above, When I perform the same request again then it gets
successful:

Lambda Authorizer Policy not restricting access to Api Gateway proxy resource

I have a Lambda authorizer (python) that returns a resource-based policy similar to the following:
import json
def lambda_handler(event, context):
resource = "*"
headerValue = _get_header_value(event, 'my-header')
if headerValue == 'a':
resource = "arn:aws:execute-api:*:*:*/*/GET/a"
return {
"principalId": f"somebody",
"policyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Action": "execute-api:Invoke",
"Effect": "Allow",
"Resource": f"{resource}"
}
]
}
}
Basically, this authorizer will return an unrestricted api resource policy by default, using *. However, if a specific header value is passed, the policy will restrict access to only allow GET /a.
On the ApiGateway side of things, the only resource I have is ANY /{proxy+} which proxies into a .NET Core WebApi using APIGatewayProxyFunction. Inside the APIGatewayProxyFunction/WebApi, I have a number of Controllers and routes available, including GET /a. After all this is deploying into AWS, I can construct an http request using my-header with value a. I'm expecting this request to only provide access to GET /a, and return a 403 in all other cases. Instead, it provides access to everything in the api, similar to the star policy.
Is this the expected behavior when using a Lambda Authorizer in front of a proxy resource? It seems to really only enforce Allow * or Deny *. Thank you.
Note - When using the same authorizer against an Api Gateway where all the resources defined inside it (instead of inside .NET Controllers by proxy), the expected behavior does appear to happen - the http request with my-header set to 'a' will grant access to GET /a, but return 403 otherwise.

OAuth2 key/secret with github v4 graphql endpoint

How to pass the clientId and secret for github's graphql endpoint?
In documentation, they have shown it for rest endpoint but not sure how the new api (v4) will work with server to server calls.
https://developer.github.com/v3/#oauth2-keysecret
curl 'https://api.github.com/graphql?client_id=xxxx&client_secret=yyyy'
{
"message": "This endpoint requires you to be authenticated.",
"documentation_url": "https://developer.github.com/v3/#authentication"
}

AWS api gateway not working same after Deploying API

I have deployed a basic AWS API, Below are the screen shots.
now when i run Test from above and pass parameter shown in Query String of Method Request i will get the following response.
Request: /searchpatents?name=fsf&test=sfsf
Response against above request
{
"name": "fsf",
"sample": "sfsf",
"controller": "awsapi",
"action": "index",
"awsapi": {
"name": "fsf",
"sample": "sfsf"
}
}
Which shows that i can use the name and sample parameter on my HTTP endpoint.
Now i have deployed this api by clicking Deploy API button and sends HTTP request via curl and by POSTMAN after exporting it from AWS stage panel, I am not receiving name and test params.
My Integration Request is as below
Making a GET request with a body is non-standard, and API Gateway is ignoring the body in a GET request. Please try to using POST/PUT for a request with a body.