How to configure cognito authorizer on API Gateway V2? - amazon-web-services

on AWS API Gateway V1, when creating an Authorizer there're two options (Lambda and Cognito), and when choosing Cognito you just need to define the user pool (from a list) and the Token Source (usually the word "Authorization").
This way, in Cognito I can create a "App client" and with it's client_id and client_secret, the client can create an access token and call the API.
On API Gateway V2, there's no option for Cognito. They replaced by JWT option where you need to define the "Authorization" header (as API Gateway V1), the issuer URL (in this case it will be the cognito URL) and it's mandatory to define the Audience (and it's the problem for me).
The audience must be a string (can be the client_id), but defining the client_id will restrict the access on the api to only the clients that were mentioned in the audience and I would like to let it open to any client that's created on the cognito pool.
On API Gateway V2 Authorizer documentation it says the gateway will verify the aud or client_id that, but cognito access tokens do not define aud attribute, so it will force the comparison with the client_id.
Is there a way to let it open as it's on API Gateway V1?

Related

using api gateway with aws cognito for protected routes

So I'm going to put a public facing API up using AWS API Gateway, where I'll have back end lambda resources that handle the logic for each route (decoupled microservice).
What should I be storing in the JWT? Currently, I've disabled all read attributes, so the token only contains cognito:username, where in my database I will store this as the user id for each user. My understanding is that once a JWT is properly generated, I can use Cognito as an authorizer with API Gateway, and then once the token JWT details are received at the lambda layer, all I need to do is use the cognito:username key to lookup the user profile in my database.
Should I be implementing any other checks in the backend, or is it safe to rely on API gateway to pass the authenticated request?
Thanks!
The cognito API Gateway authorizer will only check if the token has not expired and if it belongs to the correct user pool. But since you will be extracting username from the token itself, you should be safe. Just make sure to configure API Gateway to pass Authorization header to the lambda, it does not do this by default.

using cognito for authentication and custom authorizer for authorization

I have an serverless application which uses AWS Cognito, Lambda, and API Gateway.
The user signs in using AWS Cognito (with external identity provider) for user authentication and authorization.
The API gateway uses Cognito Authorizer to secure access to the lambda function.
The initial use case is simple, any request sent to API Gateway need to be authenticated with Cognito, and they are authorized to invoke the lambda function. As long as they can sign in, they can invoke the lambda.
Now I want to change the authorization. Even if the user is able to authenticate with Cognito, they must contain certain scopes in order to be authorized to invoke the lambda. These scopes can be fetch or checked in an external authz service. Cognito authorizer on the API gateway do not allow me to implement custom logic to call external authz service.
What is the recommended way to handle this?
You can use lambda authorizer for this use case.
In your lambda you can first authenticate your incoming token (example) and once authentication is successful you can check authorization scopes using authz service.

How to Authorize APIGateway calls to a Lambda Function?

I have an API Gateway which is connected to a Lambda Function. And In the Method Request for a particular POST Method, I want some restricted people only to be able to call the Method.
One way I can implement that is by explicitly passing a token in the request body which I can provide to every authenticated user and then checking if a token is present in the method. Also, I saw Authorization : AWS_IAM in the Method Request details.
I am new to AWS and cannot figure out how to call the API with AWS_IAM authorization via an external Application using the URL we get after deploying the API ?
I want some restricted people only to be able to call the Method
One way of doing this is by means of API keys:
API keys are alphanumeric string values that you distribute to application developer customers to grant access to your API.
In your question you wrote about "explicitly passing a token in the request body" but it was not clear if you want to implement such a solution yourself, or use the solution provided by API Gateway (i.e. API keys)
The IAM authentication for API Gateway APIs will require to create IAM group or IAM users for those "restricted people" in your AWS Account. General steps for that are explained here:
Control access for invoking an API
How do I enable IAM authentication for API Gateway APIs?
I suggest to do this using the API Gateway Authorizers and create a Cognito Authorizer as you are already using a token of the Authenticated user you can achieve this by:
Go to your API gateway select Authorizers from the left menu.
Click on create Authorizer.
After clicking create Authorizer you will have the below screen that will give you the ability to add your existing Cognito user pool and add "Authorization" as token source.
After setting up your Authorizer you will be able to use the "idToken" returned by Cognito after an authentication and pass it in your API request as Authorization header(BEARER token).
Click on your Resources in your API Gateway and choose your lambda function and under Method Request you will be able to assign your created authorizer under (Settings -> Authorization).

Authorize AWS API Gateway with either API Key or Authorizer

In AWS API Gateway,
- We can set up a resource to reqiure API Key for access.
- We can also set up another resource to require Authorization (e.g. JWT token, handled via a lambda function or AWS Cognito).
The question: can we configure a resource to be accessible in either of the above two situations? Currently, if we enable "API Key Required" and "Authorization" simultaneously, the request needs both the API Key and the Authorization. We were hoping for it to pass with only one of the two.
Hack/workaround: Create two copies of the same resource, and authorize each separately, one with API Key and the other one with an authorizer.
Let authorizer generate/map the API key for you
You have a Lambda authorizer return the API key as part of
the authorization response. For more information on the authorization
response, see Output from an Amazon API Gateway Lambda authorizer.
Pros:
Single end-point
API key is more for usage plan than authorization. Keep it that way.
Cons:
Authorizer will run on each request. Which cost money
Authentication, Identification, Authorization are intertwined concepts. As I got more educated on Auth, here is my answer:
API Keys are used for project/application identification and authorization
JWT are used for user authentication and authorization.
API Key is on project/application scope and JWT is on user scope. In other words, API Key only identifies the application, not the user of the application.
Accordingly, it makes sense not to authorize the same endpoint with both JWT and API Key as it would reduce the governance granularity for users and applications. But, if you have a usecase that requires that type of authorization, the suggested workaround could work.

aws cognito, api gateway and cognito with postman

How do I call API gateway with postman with cognito?
Tried to use AWS Signature in postman and this did not work.
https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-use-postman-to-call-api.html
I am using hosted UI in cognito if that makes a difference. I see that there is an Oauth 2.0 option in postman but dont know how to fill out the fields.
So my api works when I pass Authorization in the header with the id_token. Without the id_token is there any other way?
thanks
If you are using a Cognito user pool and have your API Gateway authorizer set to user pool, then you need to pass either the id or access token in the Authorization header.
If you are using a Cognito identity pool and have your API Gateway authorizer set to AWS_IAM you need to use AWS signatures