I want to use the AWS API Gateway to Authorize using API Key.
However, my need is that every time some client use the API key to make request using x-api-key header, I want to see that it is for which account Id in my system.
For example: My system having userID-1 and I have created API key in API Gateway that is APIKey-1 now I want to map it in API Gateway. So,every time request comes to the downstream service I can see the API key as well as account ID.
So, from request I can identified that APIKey-1 is mapped to UserId-1 and so on.
Appreciate your help.
If any alternative, please let us know.
Thanks,
Keyur
ApiKeys is not recommended way to authorizer users. You should try using one of API gateway supported authorization solutions.
Why can't you push this mapping ( apikey to user ) to your backend ?
Related
Let's say I have an AWS API Gateway. I have a resource in said gateway that requires the use of a gateway API Key. I would like my server to know which of my various keys are being used to authenticate (just for logging; there's no access control happening based on this).
How do I include the name of the gateway API Key in the request that is being sent to the server?
Firstly, you mentioned logging which keys are used for authentication. API GW API Keys are intended to be used with usage plans, not authentication/authorization (link).
For user authentication and authorization, don't use API keys. Use an IAM role, a Lambda authorizer, or an Amazon Cognito user pool.
I think it is because of this reason, AWS does not forward the key further to the backend. Furthermore, if you have used one of the authorizers like Lambda or Cognito, your backend will have a way to log the authenticated identity.
If you really want to log the API keys though, I think you can use a mapping template to explicitly tell API GW to forward the x-api-key header.
API keys attached to an API gateway have to be unique. From the docs:
API key values must be unique. If you try to create two API keys with different names and the same value, API Gateway considers them to be the same API key.
The is no such header to specify the name of the key. You can create your own custom header where you would add this information, but nothing would guarantee that the correct name is sent with a given API key. You would probably want to implement a call using the AWS SDK from your server to retrieve the name of the API key.
In case you are using a Lambda authorizer function, you can fetch the name of the API key in this function and forward it as a header to the backend server.
I have a REST API with usage plans configured on AWS API Gateway.
I want to send an email to the users of the API if they have used > 90% of their plan. What would be the best way to do it?
Is it possible to add the usage information for an API key into the header of the request that comes through API Gateway to the server?
Alternatively, I could use API Gateway REST API, I suppose. I am afraid though that it won't scale to the level of invoke requests against deployed APIs.
You can use cloudwatch to store the number of api calls on the bases of apiid and set an alert on that which will trigger an email
I want to use api-keys for authorization and grouping users for accesing the api's in API Gateway. The requests will be sent from web-page using javascript calls.
Is there any way to encrypt the api-keys?
Lets say I am able to encrypt it, will it be beneficial at all? Because someone can still see the encrypted api-keys and use it, and it will still work, because anyhow i will be decrypting it somewhere.
Is there any better way?
You cannot protect your API keys for authorization when your API calls are initiated from the client (i.e., JavaScript). As you said, there will be no point of encrypting them as well. You'll need to have an authorization provider that can return the API key as part of the response.
API Gateway allows you to have custom authorizer for your API. See Output from an Amazon API Gateway Custom Authorizer.
I'd like to add a default throttled API key for unauthenticated requests to prevent abuse.
How would I do this in API Gateway?
EDIT
To make it clearer what I need, how do I transform a request in API Gateway? Is this possible?
I would say using Cognito is the best way of authorizing API gateway.
If you want a default API key then you can go for custom API gateway authorizer. Please have a look on official documentation for the same here
You need to store the API Key in the Server Side of your application and shouldn't expose it to the Client Side (Although API Key is not considered as a security token, it can be used by malicious party to call your API).
There are couple of options you have based on the nature of your application consuming the API.
If it is a single page web application where front-end is hosted in S3, you can use AWS CloudFront to store the API Key in headers and forward it to the API Gateway, while also serving the frontend through the same CloudFront distribution. This will also remove the cross origin resource sharing problem between your web application and API Gateway.
If you have a web server, you can store the API Key at Web Server and use to proxy request to the API Gateway while setting the API Key header value.
Note: Don't use API Key for authentication which is not recommended.
This is how I would solve it.
Create Usage Plan with the throttle, burst and max limit on the request allowed.
http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/APIGateway.html#createUsagePlan-property
API Key:
Create API Key (createApiKey) and associate it (createUsagePlanKey) with Usage Plan already defined. That will allow the limit defined for the requests received.
http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/APIGateway.html#createApiKey-property
http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/APIGateway.html#createUsagePlanKey-property
Have a separate lambda to monitor the Generated API-Keys and cleanup once it is expired, so you will not flood API-Gateway with unused keys.
If you take it to CloudFront, you can create Self Signed URL, that will be valid for a given period of time. After that time limit URL will be invalid. This is to keep yourself time-limited for the user, so within the given timelimit, what resource they can access.
One more usecase, we worked on, you can authenticate the user only on certain urls with custom Authorizer. Any other urls that get invokes, will return unauthorized without any additional code.
Hope it helps.
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