Part 3:Securing AWS API Gateway using JWT Authorizer & Okta JWT Access Token

karthik
7 min readDec 9, 2021

--

In the previous blog, we saw how to secure APIs using OAuth2 client credentials grant and built-in Cognito Authorizer. Refer the below blog for more details :

In this blog, we are going to use the same AWS API Gateway, but the built-in JWT Authorizer to validate JWT Tokens generated from Okta. JWT Authorizer is a great feature because it performs all the validations and authorization checks with minimal configuration.

Below is the architecture diagram :

  1. The client application will invoke Okta /token endpoint using OAuth2 client_credentials grant to get a JWT access token
  2. Okta will return a JWT access token
  3. Invoke the API configured in AWS API Gateway by passing the Okta JWT token in Authorization header
  4. AWS API gateway’s built-in JWT Authorizer will validate the JWT token by getting the public key from Okta’s jwks_uri. There are some additional validations that are performed. Refer https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-jwt-authorizer.html for more details.
  5. Built-in JWT Authorizer will return the status of token validation to AWS API gateway. This happens in the background.
  6. API gateway will forward the request to target API endpoint if all the validations are successful. If the token is invalid or the required scopes are not present, API gateway will return an error response.
  7. API endpoint will return the response back to API gateway.
  8. API gateway will return the response back to client application.

Please note that JWT Authorizer is available only with AWS API Gateway HTTP API and not with REST API. They might support JWT Authorizer for REST API in the future. Refer https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-vs-rest.html

There are a few prerequisites for setting up this integration:

  1. AWS Account — business or free tier.
  2. Okta developer account
  3. Knowledge of AWS API Gateway
  4. Knowledge of OAuth2 protocol. In case you are not aware of OAuth2 protocol, kindly watch this video :

We have to perform the below steps for this integration:

  1. Subscribe to Okta and configure a OAuth2 client in Okta with a custom scope
  2. Deploy a sample API Gateway HTTP API with a test endpoint
  3. Configure JWT Authorizer in API Gateway

Note: The screenshots added in this blog might look different if Okta or AWS changes their UI. But, the features should work the same way even if Admin UI is modified.

You can either follow the setup instructions in this video or go through the step-by-step instructions in this blog :

In case you are using Auth0 which is also a Okta company, follow this video :

Step 1:Subscribe to the Okta developer account and create an OAuth2 client

  • Okta is very developer friendly and they provide a free developer edition. You can login using your Google account to https://developer.okta.com/signup/
  • Once you login to Okta, navigate to Applications > Applications
  • Click the “Create App Integration” button and select “API Services” in the popup window
  • You can give any name. I named my API application as AWSJWTAuthTest. Click “Save” button to create the application.
  • You should see the client ID and secret
  • Next step is to add a custom OAuth2 scope to authorize the calls to AWS API gateway endpoint
  • Navigate to “Security” > “API”. You should see a default configuration with audience “api://default”.
  • Click “Add Authorization Server” and give a name, audience for your endpoint. I entered the following values :
  • It will create a new Authorization server and show the configured details. Navigate to “Scopes” tab and add a scope with following values :
  • Navigate the “Access Policies” tab and click “Add Policy”
  • Click “Add Rule” and create the following rule
  • Once the policy is created, go back to “Settings” tab and open the “Metadata URI” in a new tab
  • Copy the “token_endpoint” from the “/.well-known/oauth-authorization-server” response
  • Execute the following curl command to get a JWT Access Token
//Replace app client id and secret accordingly. URL will be the token_endpoint curl -X POST --user <app client id>:<app client secret> '<token_endpoint>?grant_type=client_credentials' -H 'Content-Type: application/x-www-form-urlencoded'
  • You should get a JWT Access token. Below is a sample token :
{
"ver": 1,
"jti": "AT.tiDL2ZI4l6SPXpK-YV8kY1dgLNgjdFwgRDE-R5Ux_78",
"iss": "<issuer value from /.well-known/oauth-authorization-server>",
"aud": "api://awsjwttest",
"iat": 1639018922,
"exp": 1639022522,
"cid": "0oa31nua7ycWpavH15d7",
"scp": [
"jwtread"
],
"sub": "0oa31nua7ycWpavH15d7"
}

Step 1:Setup a test endpoint with JWT Authorizer in AWS API gateway

  • Login to AWS Management console and search for API gateway service
  • In API gateway, navigate to APIs and choose “HTTP API” option and click “Build” button
  • Enter a name for the API. I entered “jwtauthzapi” and clicked “Review and create” button followed by “Create” button
  • You should see a screen like this :
  • Select “Routes” on the left navigation bar and “Create” a new route with method “GET” and path “/users”
  • Once the route is created, click “Attach Integration” button in “Route Details” followed by “Create and attach an integration” in the next screen
  • In the next screen, select “HTTP URI” for “Integration Type” and “GET” for “HTTP Method” and enter “https://jsonplaceholder.typicode.com/users” for “URL”. Please note that jsonplaceholder is a mock REST API service that returns some test data. You can use any mock API for this testing.
  • Click “Create” to create this integration
  • Now, get the API URL from details screen and try hitting that URL with /users in the end.
  • Next step is to add the Authorization. Navigate to “Authorization” screen
  • Click “Create and attach an authorizer” button and enter the following values. Please note that the “Issuer URL” is from the Okta’s “/.well-known/oauth-authorization-server” endpoint. “Audience” value is from the “Security” > “API” screen in Okta.
  • Now, we will get a JWT token from Okta and pass it in the header using a curl request
//Replace app client id and secret accordingly from Okta. URL will be the token_endpointcurl -X POST --user <app client id>:<app client secret> '<Okta token_endpoint>?grant_type=client_credentials' -H 'Content-Type: application/x-www-form-urlencoded'//Copy the JWT token from the previous curl request and pass it in Authorization headercurl -X GET 'https://u14wa6s0u3.execute-api.us-east-1.amazonaws.com/users' -H 'Authorization: <Okta JWT Token>'
  • If the token validation is successful, it will return the user response
  • Go back to the “Authorization” screen and click “Add Scope”. Enter the custom scope that we created in Okta “jwtread” and “Save”
  • Now, again try hitting the curl request with Authorization header. You should see the user response.
  • If you want to make sure if the scope validation is successful, try changing the scope from jwtread to jwtwrite and then hit the curl request again with the same JWT token.
  • You should get a “{“message”:”Forbidden”}” error because the token is valid, but it doesn’t have the correct scopes.

Thanks for reading this article. Please subscribe to the below YouTube channel and follow me in medium to learn about security and IAM.

--

--