How to test calls to an Amazon API gateway using Cognito Auth - amazon-web-services

I've got some lambdas behind Amazon's API Gateway, which is configured to restrict access to Cognito authenticated users. All works fine for users coming via a UI.
I'd like to test those APIs separately to the UI, using Postman ideally or failing that perhaps curl.
How can I send a Cognito-authenticated request via Postman, curl or similar, to the API Gateway?

Try using Insomnia as a Rest client: https://insomnia.rest/
I see it has a tab for AWS auth settings.

just have a look at the following post, i think it'd be helpful for you.
How setup header in Postman for Api Gateway authenticated with Cognito?

Related

is ok to choose AWS HTTP API gateway for a mobile application?

I am trying to decide which aws apigateway version choose for my application (HTTP vs REST API gateway).
I am experimenting with AWS HTTP API gateway to see if it works fine for my use case.
These are my requirements:
The only client is a mobile application
The rest API can be accessed only from logged in users
I want to use cognito with cognito authorizer
My backend is a mix of lambda services and HTTP rest services exposed via an internal application load balancer
Everything seems to be supported, the only concern is that I would have used an api key, but this feature is not currently supported on HTTP API gateway.
Are there any security concern if I go for HTTP without any api key?
What would be the right way to restrict the access only to requests coming from my mobile app?
Everything seems to be supported, the only concern is that I would have used an api key, but this feature is not currently supported on HTTP API gateway.
HTTP APIs support OpenID Connect and OAuth 2.0 authorization
https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api.html
If you have any custom api-key, you can still have an authorizer lambda to authenticate and authorize the client.
Are there any security concern if I go for HTTP without any api key?
What do you mean by the api-key? API-key is usually static shared secret used mostly in the backend application. Claiming the users need to be authenticated and using the mobile app, having a hardcoded api-key is not the best idea (read - it is a terrible idea)
Under these requirements the default option is using OAuth2/OIDC for user authorization and passing the user's access token along the API requests.
What would be the right way to restrict the access only to requests coming from my mobile app?
I want to use cognito with cognito authorizer
The simplest and built-in way is using the access token from Cognito and built-in JWT API authorizer. Yet you may configure any other option.

Authenticate session with AWS API Gateway

Situation: I have an app (Next.js/React on Vercel) running on example.com. I have an api (AWS API Gateway) on api.example.com. Currently the application on example.com supports login using Auth0 as authentication provider.
Problem: I would like to be able to make authenticated requests from the application (example.com) to the api (api.example.com).
Architecturally, I was hoping for a way for the API Gateway (api.example.com) to handle the authenticated session from the app/Auth0 cookie (example.com). I thought the browser could share the cookie (since api.example.com is trusted) and the API could validate it.
But I don't see a standard way to do it. I think I could try to create some custom lambda authorizer for AWS' API Gateway. But since we're dealing with authentication, I would prefer to outsource as much as humanly possible and avoid any custom code. I just can't seem to piece together the way for API Gateway to handle the sessions, which I assumed would be a pretty common problem to solve.
Sidenote: Previously, I used the pages/api that's baked into Next.js to directly call Lambdas on AWS and expose them. With this, authentication natively works. That's the experience I'm now trying to recreate, but without the user having to take a roundtrip.
When you want to protect APIs it’s better to use JWT tokens to carry over necessary claims e.g. id of authenticated user. OpenID connect and Oauth2.0 are the standards to look into.
Auth0 has documentation of recommended authentication flow: https://auth0.com/docs/flows/authorization-code-flow
as well as example with Api Gateway’s HTTP apis: https://auth0.com/blog/securing-aws-http-apis-with-jwt-authorizers/
AWS documentation has more info about Http Apis and JWT token authorizers: https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-jwt-authorizer.html
If your Api gateway is using Rest apis instead of more light-way Http apis then token based Lambda authorizers are the right solution: https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html

Securing HTTP endpoints of Cloud Functions - GCP

I have created CF on GCP console, some are trigggered by Firestore and some are HTTP Endpoints. I have secured former one using Firebase Auth, but the later one HTTP Endpoints are not secured as i didnt find any way to authenticate them. Please help as i am new to GCP.
Here's a code sample that shows how to only allow users that use a Firebase ID token as a Bearer in the Authorization header of the HTTP request or in a __session cookie to trigger the Cloud Function.
Alternatively this StackOverflow post may be of help.

Do I need to verify a AWS Cognito token in BOTH Lambda AND as API Gateway?

When using a AWS Cognito attribute from a JWT token in a lambda, do I need to verify the JWT? The Lambda is only triggered by an API Gateway which already verifies the token.
Adding details:
- I'm using Cognito Authorizer in the API Gateway to verify the token.
- The lambda is connected to the API Gateway as proxy.
No you don't need to verify the JWT in backend lambda if protected by a custom lambda authorizer by API Gateway. I would suggest you to use REQUEST based lambda authorizer and attach attributes in the response. So your backend lambda will be able to access attributes in event.requestContext.authorizer['your_attribue'].
This will also enable you to test your Lambda in isolation without needing to get attribute from JWT. You can always mock the event object for unit testing.
I ran into the same conundrum, and was trying to find documented confirmation that, within the Lambda, I wouldn't have to do any validation on my own, and that I can safely rely on the the token / claims being genuine. Unfortunately, nothing in the AWS documentation or the forum posts that I've seen so far has explicitly confirmed this.
But I did find something similar for GCP, and how the API Gateway there validates the JWT. From the GCP documentation:
To authenticate a user, a client application must send a JSON Web
Token (JWT) in the authorization header of the HTTP request to your
backend API. API Gateway validates the token on behalf of your API, so
you don't have to add any code in your API to process the
authentication. However, you do need to configure the API config for
your gateway to support your chosen authentication methods.
API Gateway validates a JWT in a performant way by using the JWT
issuer's JSON Web Key Set (JWKS). The location of the JWKS is
specified in the x-google-jwks_uri field of the gateway's API config.
API Gateway caches the JWKS for five minutes and refreshes it every
five minutes.
So, it seems that within GCP at least, we don't have to do anything, and the API Gateway will handle everything. Even though this is not a confirmation that this is how it works in AWS as well, but the fact that this is how it works in GCP, it gives me some more confidence in assuming that it must be so in AWS too.

How do I use AWS cognito response to authenticate API requests

I am building a web app that authenticates via AWS Cognito, and uses an existing API gateway configuration to talk to Lambda functions.
In my app, when I authenticate, I get the following data back from Cognito:
The sample headers I've been given to authenticate to the Amazon API gateway look like this (x's added for obfuscation):
Content-type: application/json
Host: <API Gateway host>
X-Amz-DateL <Date>
Authorization:
AWS4-HMAC-SHA256 Credential=XXXXXXXXXXXX/20170222/ap-southeast-2/execute-api/aws4_request, SignedHeaders=content-type;host;x-amz-date, Signature=f25e2a18d8c81fe9e7XXXXXXXXXXXXXXXXb7d586d24a3e39
Access_key:XXXXXXXX (this is a large string)
My question is what information do I need from my cognito result to craft the headers that I need to connect to the api?
I'm using Vue.js as a Javascript front end, and I've looked at the AWS SDK for Javascript but not sure if that helps me - for the moment I feel crafting the headers manually may be easier?
I believe what you're trying to do is authorize your already authenticated users. Explanation of the difference between authorization and authentication can be found here
In the case of authorization, you can create a Custom Authorizer. However, since you're using Amazon Cognito, be sure to create a Cognito User Pool Authorizer
Essentially, you'll use the IdToken from Cognito and pass it as the Authorization header to your authorizer function.
See also Integrating Amazon Cognito User Pools with API Gateway