Use JWT Authorizers with WSO2 Identity Server and AWS API Gateway HTTP APIs

[Source :https://media.giphy.com/media/lfgxIvUa1FPfWj54jI/giphy.gif]

JWT Authorizer is a new feature introduced in AWS API Gateway which can be used to control the access of APIs deployed in AWS Api Gateway using Jason Web Jokens (JWT).

These Jason Web Tokens need to be used can be obtained by any external Identity Provider and today I’m gonna talk about how to use JWT Authorizers to restrict access to the API’s in AWS API Gateway using an access token issued by WSO2 Identity Server.

Img1 : General flow

Check the whole flow happening here below.

  1. The client application sends a HTTP request to the API with the JWT access token obtained from WSO2 Identity Server as an Authorization header in the API request.
  2. The request received by the API Gateway of AWS sends the JWT access token to JWT Authorizer for validation.
  3. JWT Authorizer sends a request to the WSO2 Identity server’s JWKS endpoint to get the public key of the authorization server in order to validate the JWT token.
  4. WSO2 Identity Server returns the public key to the JWT Authorizer.
  5. JWT Authorizer validates the JWT access token.
  6. API Gateway runs the lambda functions and processes the request.
  7. API gateway returns the Http response to the client application.

Let’s move in to the steps need to be followed to test above mentioned scenario.

Step 1: Configure WSO2 Identity Server to obtain a JWT access token.

  1. Configure a service provider in WSO2 Identity Server under OpenId connect configurations. (You can use any preferred grant type here.)
  2. Add the Token Issuer as “JWT”.
  3. Send a request to the WSO2 Identity Server and obtain a JWT access token.

Step 2: Create a HTTP API and a Lambda function on AWS.

  1. Refer below documentation to create a http api in AWS API gateway.​​https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop.html#http-api-examples
  2. Navigate to AWS console and Create a simple lambda function and deploy it. (You can write any preferred business logic here)
  3. Navigate to the AWS API Gateway and click on Build on HTTP API.
Img 2 :Create an API in AWS API Gateway

Note : Make sure to select the created Lambda function in the Lambda function drop down and click on Next.

4. Configure routes with preferred methods and resource paths.

5. Finish creating the API after reviewing.

Review api
Img 3: Review API

6. To test the created API, copy the Invoke url of the created API and navigate to postman.

7. Add the Get method resource path and send a GET request to test the API.

Img 4 :Test the created API

Now we have finished creating a new Http API with a simple lambda function and you will be able to see that a User can access the GET method of the created API without any restrictions.

Let’s see how to restrict the access to the above created API using a JWT Authorizer.

Step 3: Add a JWT Authorizer to Your API

Let’s add the JWT Authorization header to restrict the access to this API’s GET method only for the users who are having valid access tokens issued by WSO2IS.(Users who are only successfully authenticated from WSO2IS)

  1. Navigate to the API created and click on Routes. Here if you click on any method you will be able to see that there are No authorizers attached to this route.
Img 5 :Route details of an API

2. Click on “Attach Authorization”.

Img 6 :Attach Authorization

3. Then click on Create and attach an authorizer.

Img 7 :Select JWT Authorizer

4. Here select JWT as the Authorizer type and enter the other information as below.

Img 8 : Enter information of Identity Provider

Let’s get to know what these fields are :

  • Name : A name for the authorizer. You can enter any name you prefer.
  • Identity source : In which part of the request you are sending the JWT token. Header, body etc. Since we are sending in the request header as the Authorization Header here, we configure as $request.header.Authorization
  • Issuer URL : The issuer url of the WSO2 Identity Server. This must be equal to the “iss” value of the decoded JWT token.
  • Audience : Client id value of the service provider configured in WSO2IS. This must be equal to the “aud” value of the decoded JWT token.

5. Click on Create and attach

Img 9 : Finish attaching the authorizer

Now you will be able to see in the Authorization tab in API, there is a JWT Auth authorizer that has been configured.

Step 4: Test It Out!

Let’s test the flow with newly added authorizer.

  1. Navigate to postman and try to send the same GET request to the api endpoint.
  2. You will be able to see that you received an error message saying “Unauthorized” .
  3. Since we added a JWT Authorizer we need to send the valid JWT token in a request header when calling the API resources.
  4. In Headers section of postman request, add a new header called “Authorization” and add the value as “<Bearer <JWT TOKEN Value>>” with the prefix Bearer.
Img 10 : Try out the API with JWT Authorization header

5. Enable the header and send the request again.

6.Now you will be able to see that you can access the API resource successfully.

🌟 You would also be able to see that if you send an expired JWT Token (Invalid token) that the access to the Api fails since the validation at the JWT Authorizer fails.

As a last note let me explain how this JWT Authorizer of AWS API Gateway validates the external identity provider’s JWT token.

As you may know there are two ways,

  • To let the external Identity Provider to validate the JWT token, and ask for a valid response, (Here you will need to integrate the AWS API gateway with external IDP (WSO2 IS).)
  • And to obtain the public certificate of external Identity Provider and validate it by it self.

In JWT authorizer of AWS API Gateway uses the second approach.

API Gateway uses the following general workflow to authorize requests to routes that are configured to use a JWT authorizer. (Source: https://github.com/awsdocs/amazon-api-gateway-developer-guide/blob/eab79ce74f7e8ec59567fea32f804d8ba4570f35/doc_source/http-api-jwt-authorizer.md)

  1. Check the identity source for a token. This can include only the token or token prefixed with Bearer.
  2. Decode the token.
  3. Check the token’s algorithm and signature by using the public key that is fetched from the issuer’s jwks_uri. Currently, only RSA-based algorithms are supported. (jwks_uri will be obtained by the issuer url configured and the well known end point meta data will be used.)
  4. Validate claims. API Gateway evaluates the following token claims:
  • The token must have a header claim that matches the key in the jwks_uri that signed the token.
  • Must match the issuer and Audience configured.
  • Client_id of the Service provider must match with the “aud” claim value.
  • “exp” value must be after the current time in UTC
  • “nbf” value must be before the current time in UTC.
  • “iat” value must be before the current time in UTC.

If any of above fails, the API Gateway denies the API request.

This is all about using JWT Authorizers with WSO2 Identity Server and AWS API Gateway HTTP APIs.

Hope this would help anyone who tries to achieve the validation of JWT tokens with AWS API Gateway JWT tokens with external IDPs and please leave comments and issues down there.👇

Have a great time 🥳

Software Engineer|WSO2|Graduated from University of Moratuwa