AWS API Gateway Websocket routes missing Cognito information - amazon-web-services

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.

Related

Multiple Authentication for API Gateway Resource

I want to Authorize the request to API Gateway using COGNITO_USER_POOLS or API Key, That is the incoming request can have either of authentication token(using COGNITO_USER_POOLS) or API Key
Is there anyway to configure both types of authorization and use either of one of them to authenticate on a single API Gateway resource?

AWS API Gateway Authorizer does not authorize non-default Cognito User Pool App client tokens

I have created a new app client in Cognito, the tokens from the default app client are marked as valid by the API Gateway but not the token from the new App Client.
The API Gateway responds with HTTP 401 - UnAuthorized.
This should work because both the app clients have full permissions to the underlying users stored in Cognito.
I couldn't find any relevant documents explaining this discrepancy.
So, I was linking my AWS User pool to Amazon Alexa Smart Home Skill using this blog https://aws.amazon.com/blogs/compute/amazon-cognito-for-alexa-skills-user-management/.
On successfully linking the skill, Alexa would only send the accessToken in the subsequent API's.
The AWS API Gateway authorizers only check for the ID token and will deem the request invalid if it is given an AccessToken.
Thus, the requests were failing. It has nothing to do with default or non-default app clients.
Using a Cognito custom authorizer seems the best option, will disable API Gateway authorization.

AWS: API Gateway Authorizer using access token given from ALB

I have a project that needs to make use of Lambda functions which are triggered by API Gateway with protected authorizer, i have set the resource method to require an authorization header which is the token id given in Cognito's authentication response. Basically all protected routes in the application are handled by ALB which will always check if the requested route is protected and if so then redirect to cognito's sign-in in case there is no session, after the authentication is successful, the Load Balancer will redirect the request to the application with additional headers, which are:
x-amzn-oidc-data
x-amzn-oidc-accesstoken
Both are in a manner of speaking JWT with user claims from the authentication. Normally the API Gateway endpoint protected by cognito authorizer requires a token id which is easily retreived using the implicit flow in cognito's authentication, but the ALB is using the authorization code flow which only gives a session code. Both data from x-amzn-oidc-data and token id looks the same but when i try to access the endpoint using the data from ALB i only get unauthorized.
The ideal flow goes like this:
I know i could avoid all this process by just implementing the Lambda function directly to ALB as trigger but my project is only looking for automated deployments and CloudFormation still does not support Lambda implementations for ELB.
TL:DR
The simple question is: How can i grant access in API Gateway using a token given by authorization from ALB?

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 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.