Limt AWS API Gateway endpoint with GET parameters - amazon-web-services

I have an API Gateway endpoint at some url, like this:
https://api.myapp.com/myendpoint
The people and/or services that are going to be accessing this endpoint need to pass particular parameters and values to the endpoint. Like this:
https://api.myapp.com/myendpoint?token=123456
Is it possible to limit access to the endpoint if the token parameter is missing OR if the token value is not a specific pre-determined value? Can I setup my endpoint to simply ignore calls that don't have the proper token?
I'm planning on using Lambda as the backend. Do I have to deal with this in my Lambda function? Ultimately, I'm trying to avoid unnecessary Lambda and API Gateway usage costs by random individuals making bogus calls to the endpoint. So if I can have API Gateway simply ignore these calls without spinning up Lambda that would be ideal.
If I am able to have API Gateway ignore these calls, do I still get billed for usage when bogus calls are made to the endpoint(s) that are missing the token?
The reason I'm asking is because the 3rd party service that is going to access this endpoint does not have any options for passing authentication parameters in headers or using AWS Cognito, etc. So I'm just trying to think of a simple way to limit access.

You will need to perform this validation in Lambda.
If you have a mapping for a query parameter token to the integration endpoint, then for a request like ...?token=123 API Gateway will pass the parameter to the endpoint, but for ...?token=, API Gateway will not.
API gateway does not do validation of query parameters like you want and you will be billed for the requests.

Related

Changing Rest API Endpoint Url dynamically in AWS Api Gateway

I'm looking after solution where AWS Api Gateway changes method endpoint Url dynamically.
I am familiar with stage variables and in Integration request I can change endpoint per method like (https://${stageVariables.Url}/api/DoSomething).
What I need is that information how parse endpoint is included in requests.
https://${RequestData.Url}/api/DoSomething
I have same Api in different locations and to implement centralized Api keys and logging services I try to forward all traffic through this one Api Gateway.
After first request client gets its endpoint information, but I don't know how to solve that clients next requests to Gateway should forward to that endpoint which client get earlier.
I got an answer from AWS support. They told that I have to make a lambda function to process all requests or just use Stage variables.

Rejecting an application/x-www-urlencoded call from Slack with AWS Api gateway if field doesn't match

I have POST requests coming from Slack's outgoing webhooks, which are going through the API Gateway to an AWS Lambda function.
I want to filter requests with the API gateway before they ever make it to my lambda function, to reduce the number of times the lambda function will be called, for security purposes.
Technically, it doesn't matter where the call comes from, or where it's going.
The core of my problem is that I want to know how to filter/reject an API call with the AWS Api Gateway if a field doesn't match what I expect.
For example, consider this json.
{
"body": "token=specificToken&someOtherField=someValue"
}
I want to reject the request if the token field doesn't match the expected "specificToken" value.
You can use a custom authorizer of the REQUEST type to do that. A REQUEST-type custom authorizer can use the request body for authorizing the request.
Reference: Create an API Gateway Custom Authorizer Lambda Function (Scroll down to the REQUEST type)
Basically, you write another Lambda that serves as a middleware between your API Gateway. This custom authorizer will decide whether to allow the request or to return Unauthorized to API Gateway.
We had the same requirement (verifying a request from slack with a lambda authorizer), and sadly the REQUEST type does NOT have access to the body of the request. Headers, path, querystring... but not body. This appears to be by design. See Access POST Request body from Custom Authorizer Lambda Function.
We experimented with a custom body mapping template to pull values out of the body and put them into headers, but the mapping is applied after authorisation so this does not work.
Finally, we decided to put our own token in the querystring of the webhook called by our slash command, and verify that instead, which is possible inside a REQUEST authorizer. Not as secure, but it works.

Saving some info as a session in API Gateway or lambda

I am going to design a single sign on website and in one component of my project I am using API Gateway. API Gateway is responsible to direct the to the appropriate services based on the user status so if the user is valid(the token sent from user is not expired) the related service for getting what he is requesting will be serve and if the token sent from the UI is expired then he will be sent to authorization service first. So as you noticed I need to save the tokens and their expiration dates somewhere in API gateway. Is there anyway I can achieve this via API Gateway? if not can I use lambda function to achieve this?
API Gateway and Lambda are stateless services.
You need to make use of some other persistent storage on AWS like
DynamoDB or RDS or Elasticache and call it from the Lambda function in order to implement the desired functionality.
You may also want to take a look at API Gateway Custom Authorizers on how to implement this functionality on API Gateway, using a lambda function.
I would implement a DynamoDB table and set the TTL expiry as the token expiration. That way you don't have to manage the deletion of the records. You can enhance your authentication system to add the token entry to this table.
You might be able to accomplish this with an API Gateway custom authorizer.
Walk Through of Using Custom Authorizers in API Gateway Documentation
Blog Post Introducing Customer Authorizers

Is it possible to use AWS Lambda to request an oauth 2.0 token?

I am looking for ways to avoid creating an ec2 instance in order to have a valid callback URL to perform the oauth handshake.
I plan to use Lambda to connect to a remote API, but I need to be able to get the token first, which is valid only for 6 hours.
Is there any way I can make the handshake via Lambda functions?
I think Lambda along with API Gateway offer a good solution. API Gateway allows you to create a persistent, publicly accessible HTTP endpoint. You can define specific 'resources' that map HTTP methods to lambda function calls.
I'm not especially familiar with OAuth 2, but I'm imagining something like this: In API Gateway, define a resource '/callback' with a GET method that invokes your Lambda function.
Register the API Gateway endpoint as your application's callback URI, which would look something like this:
https://c1bql2cdxy.execute-api.us-east-1.amazonaws.com/callback
By doing so, the remote service will invoke your lambda function, which can then read the authorization token from the request and use it however needed, whether that involves 1) storing the token in a database for future use (and reuse) by other services, 2) directly invoking the services within the same Lambda function, etc.

Passing context / authorisation with cloudfront to lambda

This is bit tricky situation I got into here,
I set up a lambda function & API gateway, then I setup cloudfront over API gateway for faster processing and achieving benefit of all the endpoint nodes provided by AWS [It should take more time using cloudfront on top of API gateway service but I am getting better result with cloudfront layer on top of it, maybe DNS resolution and AWS internal infrastructure is better]
I setup a JAVA function inside lambda which is working perfectly fine, but I want to use Context of request maker in lambda function
public String handleRequest(UserPOJO input, Context context) {
}
If I make direct lambda function request I can achieve that but it's taking too much time executing direct lambda from my Android client, also I don't find it good to expose those details, and with cloudfront I am not sure what headers should I send so that lambda detects it's cognito role and ID using context.getIdentity().getIdentityId(); in lambda.
If someone understands my problem here and elaborate it better for other I will be glad, it is very complex to explain the problem.
Technically
I can make execution of lambda function directly with cognito credential provider authentication but Very slow
Can make API gateway request which cognito credential provider authentication, speed is better than direct lambda execution
Can make cloudfront request but stuck where I don't know how can I use cognito credential provider authorisation while making the request. Seemed faster than API gateway.
Thanks. :)
If you want to get Cognito related information in Lambda function and you are proxying your request from API Gateway, You can use the mapping template to include information you need, then you can get it from the input object.
I can make execution of lambda function directly with cognito credential provider authentication but Very slow.
I recommend you to build your Lambda function in python or javascript runtime.
Can make API gateway request which cognito credential provider authentication, speed is better than direct lambda execution
API Gateway cannot improve the performance of your Lambda function, but API Gateway can provide API management feature for your Lambda function.
Can make cloudfront request but stuck where I don't know how can I use cognito credential provider authorisation while making the request. Seemed faster than API gateway.
CloudFront doesn't have do anything with your Cognito credential. It just passes everything it gets to API Gateway.
I am not sure how adding a CloudFront distribution in front of API Gateway can make the latency better except you enable the edge side cache which is not calling your Lambda function every time.