Is it possible to access response headers in API Gateway Access Logs? I am wanting to log a Header in my response Changes for Audit Logging Purposes, so I display a message for each Action as to what effect that Action.
My Current Log Format looks like:
{
"path": "$context.path",
"requestTime": "$context.requestTime",
"username": "$context.authorizer.username",
"email": "$context.authorizer.email"
"requestId": "$context.requestId",
"status": "$context.status",
"httpMethod": "$context.httpMethod",
"ip": "$context.identity.sourceIp",
"changes": "$$$TODO$$$"
}
In $$$TODO$$$ I have tried all sorts of expressions, to no avail, I imagine this might not be possible in the Custom Access Logging and that is my problem and I just don't know it, and I'll be forced to process the more verbose logs. Currently I am sending only these fields to an Elasticsearch cluster which is working nicely, but I'm worried with this new requirement I will have to change to the normal API gateway logs, and then do more filtering and processing with potentially a custom Lambda function.
Related
I'm trying to configure API Gateway in AWS to receive webhooks from the Adyen platform.
I used API gateway integration with an S3 bucket and created an API, using the following link
https://docs.aws.amazon.com/apigateway/latest/developerguide/integrating-api-with-aws-services-s3.html
The authentication is "none" in my configuration, however i'm observing error related to authorization.
Since i'm new to APIs, I couldn't understand this.
The webhook is an HTTP post method
{
"live": "false",
"notificationItems": [
{
"NotificationRequestItem": {
"amount": {
"currency": "EUR",
"value": 0
},
"eventCode": "REPORT_AVAILABLE",
"eventDate": "2022-11-22T15:19:37+01:00",
"merchantAccountCode": "COM",
"merchantReference": "testMerchantRef1",
"pspReference": "1OW4XY4YXEFDLM0F",
"reason": "will contain the URL to the report",
"success": "true"
}
}
]
}
The response I received is
{"message":"Authorization header requires 'Credential' parameter. Authorization header requires 'Signature' parameter. Authorization header requires 'SignedHeaders' parameter. Authorization header requires existence of either a 'X-Amz-Date' or a 'Date' header. Authorization=Basic amFnYTYxOTBAZ21haWwuY29tOndJTERGSVJFQDEyMw=="}
Amazon API Gateway Configuration
enter image description here
According to the official documentation the particular error you are receiving indicates that you are trying to invoke a non-existing resource. In particular, the root cause is
A request with an "Authorization" header is sent to an API resource
path that doesn't exist.
Are you sure that you have published your API properly?
The AWS Personalize docs state that I can query my campaign and solution like so:
POST /personalize-ranking HTTP/1.1
Content-type: application/json
{
"campaignArn": "string",
"context": {
"string" : "string"
},
"filterArn": "string",
"inputList": [ "string" ],
"userId": "string"
}
You will notice that there is no reference to any fully defined endpoint, or how to set one up. Further in the docs, there is only references to making this call using AWS wrappers/SDKs. I cannot use a wrapper for my use case. I need to know how to define an endpoint in a way that I can make this call from a curl command or javascript fetch call, for example. When creating an API gateway, Personalize is not a selectable AWS service.
How do I find/create the URL that I can querying against to get AWS Personalize data?
My application authenticates users using AWS Federated Identities and AWS Cognito.
Using the credentials obtained through authentication, users can call a Lambda function (using Lambda.invoke, not API gateway).
I want to know the identity of the user invoking the Lambda function (sub, username, ect), and I do get the following JSON object as context:
{
"callbackWaitsForEmptyEventLoop": true,
"functionVersion": "$LATEST",
"functionName": "name-of-function",
"memoryLimitInMB": "1024",
"logGroupName": "/aws/lambda/name-of-function",
"logStreamName": "2019/08/21/[$LATEST]xxxxxxxx",
"identity": {
"cognitoIdentityId": "eu-central-1:xxxx",
"cognitoIdentityPoolId": "eu-central-1:xxxx"
},
"invokedFunctionArn": "arn:aws:lambda:eu-central-1:xxxx",
"awsR
equestId": "3f2fc991-26b9-4eb6-aba9-4c15d6f8f0bb"
}
It's apparently really difficult to map the cognitoIdentityId to a cognito user.
Question: Is there any way to tell Lambda to add the users SUB in the context?
I'm totally stunned by how difficult this seems to be and I'm starting to think that I misunderstand something - such a fundamental operation must be possible!
UPDATE: I just noticed in the CloudWatch logs, that the content type has somehow mutated from application/json to text/plain. Here is what the WebHost string looks like now:
[Information] Microsoft.AspNetCore.Hosting.Internal.WebHost: Request starting POST https://snip.execute-api.us-west-2.amazonaws.com/Stage/api/Clinician text/plain
This is what it looked like when the call was working:
[Information] Microsoft.AspNetCore.Hosting.Internal.WebHost: Request starting POST https://snip.execute-api.us-west-2.amazonaws.com/Stage/api/Clinician application/json
And yet, the header in Postman sets Content-Type: application/json
So why is the content type changing?
Beginning of original post:
I'm developing an API Gateway Lambda Function using Visual Studio 2017 "Serverless Application with Test" blueprint which is a .NET CORE solution. We are using Cognito User Pools for authentication. I am using Postman to test my first function. I'm passing a valid ID Token for a User in a Cognito User Pool. The request passes authentication but responds with a 415 Unsupported Media Type.
Before I started passing an ID Token, I was using AWS_IAM authorizer. At that time, the body (content-type: application/json) would map to the POST parameter successfully. But now that I am using the Cognito User Pool authorizer, I get a 415 Unsupported Media Type when calling POST. The POST method signature is:
[HttpPost]
public APIGatewayProxyResponse Post([FromBody]Clinician user)
The sample data I am sending in the body is:
{
"Id": "",
"Username": "6punk",
"Title": "Punker",
"FirstName": "Six",
"MIddleName": "",
"LastName": "Punk",
"Suffix": "",
"PreferredFirstName": "",
"PreferredLastName": "",
"Email": "bogus#email.com",
"Phone": "+18015551206",
"UserSub": "",
"ClinicianTypeId": "1",
"EhrId": ""
}
As already mentioned, when authenticating as an IAM user or when testing via the Method Test pane in the API Gateway Console, the JSON maps perfectly to the Clinician class.
I have CORS enabled.
For the ANY method, I have the Integration Request type set to LAMBDA_PROXY.
Any ideas what is causing the 415 Unsupported Media Type when testing my POST method from Postman with an ID Token from a Cognito User?
As it turns out, it was a bug in Postman. Even though I had specified the Content-type as application/json, it was passing the content type as text/plain. I deleted the Content-Type header and then recreated it and things started working. I had had Postman up for several days. I don't know for certain why it started passing text/plain. All I know is that when I deleted and recreated the Content-Type header as application/json, only then did things start working again.
I want to get the IAM policy for a user using
https://cloud.google.com/resource-manager/reference/rest/v1/projects/getIamPolicy
When I enter a userid into the resource field though, I get
{
"error": {
"code": 400,
"message": "Invalid JSON payload received. Unknown name \"body_resource\": Cannot find field.",
"status": "INVALID_ARGUMENT",
"details": [
{
"#type": "type.googleapis.com/google.rpc.BadRequest",
"fieldViolations": [
{
"description": "Invalid JSON payload received. Unknown name \"body_resource\": Cannot find field."
}
]
}
]
}
}
What should I put in the request body to get the IAM policy for this user? Or is the error wrong and Users just dont have resource policies like this?
EDIT: To be clear, I get this error no matter what I put in the resource field
I think right now the UI for this API is broken and doesn't work from the browser, I get the same error.
You can however try calling it from the API explorer, or by making the call using the api client libraries as shown in the examples at the bottom of the page you linked.
The in-page explorer did have a bug, but the fix is rolling out now.
This was caused by an issue with how the GAPI library calls APIs with a parameter called 'resource', so it should only have affected pages with such a parameter in their method.