This sample shows how to integrate JWT token authorization with Amazon API Gateway utilizing AWS CDK.
The flavor of API used in this sample is the HTTP API. This natively supports JWT token validation without having to create a separate authorizer Lambda function.
The token issuing service used in this sample is Amazon Cognito.
This solution is native to AWS, and there is no need to set up a separate JWT token issuer/service. Cognito handles User management and the generation of their tokens via User Pools.
One caveat of using the HTTP API flavor (of API Gateway) is that it does not natively integrate with AWS WAF yet. You need to set up a few more pieces to get that working.
The typical workflow would be that a client application (or a user) would request a JWT token from Cognito using credentials (such as a username and password).
That token would then be supplied in the request header destined for the API Gateway endpoint. Since this sample uses the HTTP API, it can natively validate that token, and forward the request ahead.
API Gateway can integrate with many AWS Services. In this sample, it is connecting to a simple lambda function which returns a simple "Hello" message.
-
Since this is a TypeScript CDK project, you should have npm installed (which is the package manager for TypeScript/JavaScript).
- You can find installation instructions for npm here.
-
Additionally, it would be required for your to have AWS CLI installed on your computer.
pip install awscli
. This means need to have python installed on your computer (if it is not already installed.)- You need to also configure and authenticate your AWS CLI to be able to interact with AWS programmatically. Detailed instructions of how you could do that are provided here
npm install
# make sure you are in the root directory of this project
npx cdk deploy HttpApiGatewayJwtCognitoStack
# you can optionally specify the --profile flag to specify a specific non-default AWS profile
This will deploy:
- A Cognito User Pool, and an application integration client associated with that user pool
- An API Gateway (HTTP API), and a Lambda function
- Role(s) for API Gateway and Lambda function
The code defining this infrastructure is in the http-api-gateway-jwt-cognito-stack.ts file in the lib directory.
The invocation URL for the API can be found in the API Gateway console (specifically in the Stages section). You will need it to test the API request.
-
You can do this in the Cognito console.
-
You can also use the AWS CLI for this. The cognito-idp API reference is here. Specific calls are:
-
There is another utility from aws-samples you can use to ease user creation. It is called cognito-user-token-helper. You can use that script to create a new user by using the
-a create-new-user
flag and supply the--user-pool-id
with the ID of the User pool that was created as part of the infrastructure deployment. More detailed instructions are provided in that project.
After you've created a user in the Cognito User Pool, you can request for a JWT ID token for the API.
-
This can be done programmatically via the AWS CLI. You need to invoke an auth initiation like admin-initiate-auth. You can obtain the "IdToken" as the JWT token from the response of the API call.
-
The cognito-user-token-helper utility is another option that you can use to obtain a token from cognito. You can use the
-a generate-token
flag, and supply the--user-pool-id
with the ID of the user pool, and supply the--client-id
flag with the application integration client ID. Both the User Pool and Application Integration Client are created as part of the infrastructure deployment.
Once the token is obtained, you can now send a request to the API via Postman, cURL, HTTPie etc.
The endpoint is a simple GET
request on the /hello
route.
The example shown below is using curl
curl <INVOKE_URL_FROM_API_GATEWAY>/hello -H "Authorization: Bearer <JWT_TOKEN_STRING_GOES_HERE>"
If the request was successful, the output should look like:
"Hello from Lambda!"
The example shown below is using curl
curl <INVOKE_URL_FROM_API_GATEWAY>/hello
# NOTE - the authorization header was not provided in this request
The output should look like:
{"message":"Unauthorized"}
This is a blank project for CDK development with TypeScript.
The cdk.json
file tells the CDK Toolkit how to execute your app.
npm run build
compile typescript to jsnpm run watch
watch for changes and compilenpm run test
perform the jest unit testscdk deploy
deploy this stack to your default AWS account/regioncdk diff
compare deployed stack with current statecdk synth
emits the synthesized CloudFormation template