AWS API Gateway Cognito Authorizer pass claims on integration-request with HTTP proxy - amazon-web-services

I have an express application running on an ECS instance, which is connected to the API Gateway. Users are authenticated by Cognito. I added the Cognito authorizer in front of the endpoints, and it works just fine. My problem is that I don't want to decode the token in the backend, and I want Cognito authorizer to pass the verified and already decoded claims into the request.
I am aware that from the integration request, using mapping templates, I can map the values and append them to the body of the request using following.
{
"context": {
"email": "$context.authorizer.claims.email"
}
}
But I am using http proxy, and mapping template is not available when using gateway as proxy.
I was wondering if there is way to make this possible while using the api gateway as http proxy.

It seems that you can also append into params, query, or header by mapping a name to the value: context.authorizer.claims.email
Assuming I mapped it into header, within the app I can get this as req.headers.{name}

Related

Passing backend API Token to AWS API Gateway internally

Can anyone please help me with this Use-case?
Use-case : I've created the secure proxy for a private resource in the AWS API gateway. For private integration I've used VPClink and configured the Cognito pool authorizer. But the backend private API already have some Oauth2 token configured and I've separate API to generate the OAuth2 token. I don't want the end client to send both token via api gateway request, But want to internally pass the token which is already configured on the backend private rest API, via API Gateway.
For now I've created the proxy and I'm passing both tokens via request.
Note : I don't want to use lambda function.
For Example: You tried to hit the API Gateway Endpoints via postman with all the required parameters, now the request should first go to authenticator endpoint to generate the Oauth2 Token, Once token is generated the token should be passed internally to actual backend private resource to return the response.
Also, I want to know if it's the best approach to pass backend API token internally or we can pass both tokens i.e. Backend API Token and API Gateway authorizer token, via request.

AWS API Gateway Websocket routes missing Cognito information

I have Websocket API with $connect route authorization set to AWS_IAM. Once I connect with Cognito Identity Pool credentials, $connect route lambda integration's context has all Cognito data:
CognitoAuthenticationType=authenticated;
CognitoAuthenticationProvider=cognito-idp.us-west-2.amazonaws.com/us-west-2_xxxxxxx,cognito-idp.us-west-2.amazonaws.com/us-west-2_xxxxx:CognitoSignIn:user_id;
etc
But if I call any other Websocket route on the same connection, that route doesn't have any Cognito data.
What is the right way to get Cognito identity id in routes other then $connect?. I am using Golang SDK for lambda implementation.
I am using the AWS Gateway V2 API, with the WEBSOCKET protocol type, and Cognito (but with different credential handling than you have).
The Gateway V2 API allows the authentication lambda on the $connect route to return a context object along with the authentication response, and those context object values get passed along in the event object that gets sent to the route lambda.
The same context handling may have been added to the Gateway V1 API.
My implementation is in python, but once it settles down then I will likely convert it to Go to match the rest of the project.

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.

Using AWS API Gateway for Lumen based REST API Service with Passport authentication hosted in EC2

I am entirely newbie in Amazon Web services. Currently i am developed a REST API service using Laravel's micro frameworks called Lumen. I am using passport for token based authentication and all that working fine. I need a proxy server to hide my actual endpoints and do some other functionality so i am planning to use AWS API Proxy Gateway and host the API endpoints in EC2 instance.
i went through Build an API with HTTP Proxy Integration from Aws documentation. but there is nothing about using a custom authentication using Oauth.
My Doubts are
How to use Passport authentication when using AWS API Gateway
Is there any good method to hide my REST Endpoint from customer and need a way to change the proxy end point from time to time.
I don't know Laravel ecosystem, but:
if passport expose something like an OpenId Connect you could use Cognito Federated Identities for, precisely, federate your identity, and associate the authorized identities with a given IAM role and unauthorized with another role;
you can use an Api Gateway Custom Authorizer to perform fully customizable auth;
Try expanding your question so we could add more details...
Yes, like what BAD_SEED said, you can use API Gateway Lambda authorizer (formerly known as the custom authorizer) to do any logic to verify the token, since it's just a javascript package.
So, one option is like what auth0 does in (https://auth0.com/docs/integrations/aws-api-gateway/custom-authorizers/part-3) and (https://github.com/auth0-samples/jwt-rsa-aws-custom-authorizer). Their sample authorizer does followings:
It confirms that an OAuth2 bearer token has been passed via the Authorization header.
It confirms that the token is a JWT that has been signed using the RS256 algorithm with a specific public key
It obtains the public key by inspecting the configuration returned by a configured JWKS endpoint
It also ensures that the JWT has the required Issuer (iss claim) and Audience (aud claim)
But unfortunately, Passport does not support JWKS endpoint (which exposes public key for the token signature). So you may have to expose it by yourself.
Another option is much easier, you just make a token verification endpoint in your application, something like /users/me, and protect it with auth middleware. Then in your Lambda authorizer, call it with the token in the request to your other micro service endpoints. By this way, all token verification stuff is left to Passport, and the authorizer just executes policy based on the result of the verification.
Not very sure about what you want to reach, but API Gateway is just a proxy, so you can certainly change backend side endpoints for its frontend one, which is better not changing so often.

How to configure AWS API gateway to work with basic http authentication

I'm trying to configure AWS API Gateway for a Lambda function which receive the event Webhook request from Sendgrid (https://sendgrid.com/docs/API_Reference/Webhooks/event.html).
The requests will be sent from outside of my internal system so I want to have some kind of authentication for it. But according to Sendgrid'd documents, only basic http authentication is supported. The URL will look like : http(s)://username:password#domain/foo.php
I have no idea how to setting up API Gateway so it can at least pass the username and password to the Lambda function.