fusionauth logo
search-interface-symbol
Quickstarts
API Docs
SDK
search-interface-symbol
talk to an expert
Log In
talk to an expert
Navigate to...
  • Welcome
  • Getting Started
    • Getting Started
    • 5-minute Setup Guide
      • Overview
      • Docker
      • Fast Path
      • Sandbox
    • Setup Wizard & First Login
    • Register a User and Login
    • Self-service Registration
    • Start and Stop FusionAuth
    • Core Concepts
      • Overview
      • Users
      • Roles
      • Groups
      • Registrations
      • Applications
      • Tenants
      • Identity Providers
      • Authentication/Authorization
      • Integration Points
    • Example Apps
      • Overview
      • Dart
      • Go
      • Java
      • JavaScript
      • .NET Core
      • PHP
      • Python
      • Ruby
    • Tutorials
      • Overview
      • Java Spring
      • Python Django
      • Ruby on Rails
  • Installation Guide
    • Overview
    • System Requirements
    • Server Layout
    • Cloud
    • Cluster
    • Docker
    • Fast Path
    • Kubernetes
      • Overview
      • Deployment Guide
      • Minikube Setup
      • Amazon EKS Setup
      • Google GKE Setup
      • Microsoft AKS Setup
    • Kickstart™
    • Homebrew
    • Marketplaces
    • Packages
    • Database
    • FusionAuth App
    • FusionAuth Search
    • Common Configuration
  • Migration Guide
    • Overview
    • General
    • Auth0
    • Keycloak
    • Amazon Cognito
    • Firebase
    • Microsoft Azure AD B2C
    • Tutorial
  • Admin Guide
    • Overview
    • Account Portal
    • Config Management
    • Editions and Features
    • Key Rotation
    • Licensing
    • Monitoring
    • Prometheus Setup
    • Proxy Setup
    • Reference
      • Overview
      • Configuration
      • CORS
      • Data Types
      • Hosted Login Pages Cookies
      • Known Limitations
      • Password Hashes
    • Releases
    • Roadmap
    • Search And FusionAuth
    • Securing
    • Switch Search Engines
    • Technical Support
    • Troubleshooting
    • Upgrading
    • WebAuthn
  • Login Methods
    • Identity Providers
      • Overview
      • Apple
      • Epic Games
      • External JWT
        • Overview
        • Example
      • Facebook
      • Google
      • HYPR
      • LinkedIn
      • Nintendo
      • OpenID Connect
        • Overview
        • Amazon Cognito
        • Azure AD
        • Discord
        • Github
        • Okta
      • Sony PlayStation Network
      • Steam
      • Twitch
      • Twitter
      • SAML v2
        • Overview
        • ADFS
        • Azure AD
        • Okta
      • SAML v2 IdP Initiated
        • Overview
        • Okta
      • Xbox
    • OIDC & OAuth 2.0
      • Overview
      • Endpoints
      • Tokens
      • OAuth Modes
      • URL Validation
    • Passwordless
      • Overview
      • Magic Links
      • WebAuthn & Passkeys
    • SAML v2 IdP
      • Overview
      • Google
      • PagerDuty
      • Tableau Cloud
      • Zendesk
  • Developer Guide
    • Overview
    • API Gateways
      • Overview
      • Amazon API Gateway
      • Kong Gateway
      • ngrok Cloud Edge
    • Client Libraries & SDKs
      • Overview
      • Dart
      • Go
      • Java
      • JavaScript
      • .NET Core
      • Node
      • OpenAPI
      • PHP
      • Python
      • React
      • Ruby
      • Typescript
    • Events & Webhooks
      • Overview
      • Writing a Webhook
      • Securing Webhooks
      • Events
        • Overview
        • Audit Log Create
        • Event Log Create
        • JWT Public Key Update
        • JWT Refresh
        • JWT Refresh Token Revoke
        • Kickstart Success
        • Group Create
        • Group Create Complete
        • Group Delete
        • Group Delete Complete
        • Group Update
        • Group Update Complete
        • Group Member Add
        • Group Member Add Complete
        • Group Member Remove
        • Group Member Remove Complete
        • Group Member Update
        • Group Member Update Complete
        • User Action
        • User Bulk Create
        • User Create
        • User Create Complete
        • User Deactivate
        • User Delete
        • User Delete Complete
        • User Email Update
        • User Email Verified
        • User IdP Link
        • User IdP Unlink
        • User Login Failed
        • User Login Id Dup. Create
        • User Login Id Dup. Update
        • User Login New Device
        • User Login Success
        • User Login Suspicious
        • User Password Breach
        • User Password Reset Send
        • User Password Reset Start
        • User Password Reset Success
        • User Password Update
        • User Reactivate
        • User Reg. Create
        • User Reg. Create Complete
        • User Reg. Delete
        • User Reg. Delete Complete
        • User Registration Update
        • User Reg. Update Complete
        • User Reg. Verified
        • User 2FA Method Add
        • User 2FA Method Remove
        • User Update
        • User Update Complete
    • Guides
      • Overview
      • Application Specific Email Templates
      • Authentication Tokens
      • Exposing A Local Instance
      • JSON Web Tokens
      • Key Master
      • Localization and Internationalization
      • Multi-Factor Authentication
      • Multi-Tenant
      • Passwordless
      • Registration-based Email Verification
      • Searching With Elasticsearch
      • Securing Your APIs
      • Silent Mode
      • Single Sign-on
      • Two Factor (pre 1.26)
    • Integrations
      • Overview
      • CleanSpeak
      • Kafka
      • Twilio
    • Plugins
      • Overview
      • Writing a Plugin
      • Custom Password Hashing
    • User Control & Gating
      • Overview
      • Gate Unverified Users
      • Gate Unverified Registrations
      • User Account Lockout
  • Customization
    • Email & Templates
      • Overview
      • Configure Email
      • Email Templates
      • Email Variables
      • Message Templates
    • Lambdas
      • Overview
      • Apple Reconcile
      • Client Cred. JWT Populate
      • Epic Games Reconcile
      • External JWT Reconcile
      • Facebook Reconcile
      • Google Reconcile
      • HYPR Reconcile
      • JWT Populate
      • LDAP Connector Reconcile
      • LinkedIn Reconcile
      • Nintendo Reconcile
      • OpenID Connect Reconcile
      • SAML v2 Populate
      • SAML v2 Reconcile
      • SCIM Group Req. Converter
      • SCIM Group Resp. Convtr.
      • SCIM User Req. Converter
      • SCIM User Resp. Converter
      • Self-Service Registration
      • Sony PSN Reconcile
      • Steam Reconcile
      • Twitch Reconcile
      • Twitter Reconcile
      • Xbox Reconcile
    • Messengers
      • Overview
      • Generic Messenger
      • Twilio Messenger
    • Themes
      • Overview
      • Examples
      • Helpers
      • Localization
      • Template Variables
      • Kickstart Custom Theme
  • Premium Features
    • Overview
    • Advanced Registration Forms
    • Advanced Threat Detection
    • Application Specific Themes
    • Breached Password Detection
    • Connectors
      • Overview
      • Generic Connector
      • LDAP Connector
      • FusionAuth Connector
    • Entity Management
    • SCIM
      • Overview
      • Azure AD Client
      • Okta Client
      • SCIM-SDK
    • Self Service Account Mgmt
      • Overview
      • Updating User Data & Password
      • Add Two-Factor Authenticator
      • Add Two-Factor Email
      • Add Two-Factor SMS
      • Add WebAuthn Passkey
      • Customizing
      • Troubleshooting
    • WebAuthn
  • APIs
    • Overview
    • Authentication
    • Errors
    • API Explorer
    • Actioning Users
    • API Keys
    • Applications
    • Audit Logs
    • Connectors
      • Overview
      • Generic
      • LDAP
    • Consents
    • Emails
    • Entity Management
      • Overview
      • Entities
      • Entity Types
      • Grants
    • Event Logs
    • Families
    • Forms
    • Form Fields
    • Groups
    • Identity Providers
      • Overview
      • Links
      • Apple
      • External JWT
      • Epic Games
      • Facebook
      • Google
      • HYPR
      • LinkedIn
      • Nintendo
      • OpenID Connect
      • SAML v2
      • SAML v2 IdP Initiated
      • Sony PlayStation Network
      • Steam
      • Twitch
      • Twitter
      • Xbox
    • Integrations
    • IP Access Control Lists
    • JWT
    • Keys
    • Lambdas
    • Login
    • Message Templates
    • Messengers
      • Overview
      • Generic
      • Twilio
    • Multi-Factor/Two Factor
    • Passwordless
    • Reactor
    • Registrations
    • Reports
    • SCIM
      • Overview
      • SCIM User
      • SCIM Group
      • SCIM EnterpriseUser
      • SCIM Service Provider Config.
    • System
    • Tenants
    • Themes
    • Users
    • User Actions
    • User Action Reasons
    • User Comments
    • WebAuthn
    • Webhooks
  • Release Notes

    Amazon API Gateway

    Overview

    Amazon API Gateway is an AWS service for creating, publishing, maintaining, monitoring, and securing REST, HTTP, and WebSocket APIs at any scale. You can create APIs for AWS services or other web services.

    You can configure Amazon API Gateway to handle authentication and authorization to a resource through JSON Web Tokens (JWTs) issued on behalf of a user by an identity provider.

    In this document, you’ll learn how to set up Amazon API Gateway and FusionAuth as the identity provider to protect a lambda function running on your AWS cloud instance.

    Prerequisites

    • A FusionAuth instance running on a publicly accessible URL. You can spin up a basic FusionAuth Cloud instance or install it on any server. If you are not able to host FusionAuth on a public server, you can tunnel your local instance of FusionAuth through a tool like ngrok.

    • An AWS account.

    Exposing FusionAuth Publicly

    If your FusionAuth instance is already publicly available, you can skip this section.

    If you are hosting FusionAuth locally and want to expose it publicly using ngrok, you can run the following command:

    Exposing a local FusionAuth instance through ngrok
    
    ngrok http 9011

    This assumes your local FusionAuth instance is running on port 9011, which is the default for local FusionAuth installations.

    Look for the Forwarding line in the output. It should look something like this:

    Output forwarding address from ngrok
    
    Forwarding    https://7817-102-218-66-2.eu.ngrok.io -> http://localhost:9011

    The forwarding address will be publicly accessible and you can use this to replace <YOUR_FUSIONAUTH_URL> in this tutorial.

    Set Up FusionAuth

    Navigate to your FusionAuth instance.

    First, you need to make sure the JWT issuer setting is correct. Navigate to Tenants → Your Tenant and change the issuer to the URL of your FusionAuth instance. For example, https://local.fusionauth.io. Record this value, as we’ll set it in the AWS Gateway API Authorizer later.

    Next, you need to configure an application that will issue tokens to access the Amazon API Gateway project.

    Navigate to Applications and create a new application. Fill out the Name field, then click the OAuth tab.

    Make sure that the Enabled grants checkboxes have the Authorization Code and Refresh Token grants enabled.

    Your application should look like this.

    The FusionAuth example configuration

    On the JWT tab, toggle the Enabled field and set the Access Token signing key and Id Token signing key to Auto generate a new key on save…​

    The JWT configuration

    Click the Save button.

    Edit the new application. You should see a value in the Client Id field. Copy it and put it in a text file. You’ll use it in the Set Up AWS API Gateway step.

    Extracting the Client Id and secret

    Set Up AWS API Gateway

    Navigate to your AWS Console or create an AWS account if you haven’t got one already.

    Search for API Gateway in the top bar and click it.

    The AWS search for API Gateway

    Select Build HTTP API from the API type list.

    Choose HTTP API build

    Name the API. This is for your description only, so it can be anything. Then click Next.

    Name the HTTP API build

    On the Configure Routes page, click Next without setting anything. We’ll add the route via the lambda function we’ll create in a bit.

    On the Configure Stages page, click Next, leaving the defaults.

    Finally, click Create on the Review and Create page.

    A summary page for the API should appear. Copy the Invoke URL from the $default stage under the stages section. This will be the base URL for the API. We’ll add a lambda function next, which will give us a route to call.

    Create a Lambda Function to Secure

    In the main AWS search bar, search for and select lambda.

    Click Create function to create a new lambda function. Name the function privateFunction and leave all the other options as the defaults. For the purposes of this document, the code you will add here is going to return all the user claims, but in a real-world situation, you would have business logic or functionality here. Click Create Function at the bottom of the page.

    Name the Lambda

    Under the Code tab for the lambda, click on the "index.mjs" file and replace the contents with the following code to return the claims found in the JWT:

    Lambda function to reflect user claims
    
    export const handler = async(event) => {
        const claims = event.requestContext.authorizer.claims;
        const response = {
            statusCode: 200,
            body: JSON.stringify(claims),
        };
        return response;
    };

    Then click the Deploy button to update the lambda.

    Expand Function overview near the top of the page. Then click on Add Trigger.

    Under Trigger Configuration, choose API Gateway as the source. Select Use an existing API and then select the API gateway set up earlier. Select the $default deployment stage.

    Under Security, choose Create a JWT authorizer.

    Set Identity source to $request.header.Authorization.

    For API Gateway Issuer, set the value to be the same URL as you set for the Issuer in the FusionAuth Tenant configuration. Make sure that it is exactly the same, including trailing slashes, without any white space.

    Under Audiences, paste in the Client Id from the FusionAuth application created earlier.

    Then click the primary Add button at the bottom right of the screen.

    Create Lambda Trigger

    After completing this, a new route will be added to your gateway API with the same name as the lambda: privateFunction. Combine the lambda function name with the "Invoke URL" value recorded earlier when setting up the API gateway to get the full URL.

    Your full URL should look similar to this: https://w3miabt10d.execute-api.us-east-2.amazonaws.com/privateFunction.

    If you call this route through a browser, Postman, or curl, you will receive a 401 HTTP status code and an Unauthorized message. We’ll create a token next with FusionAuth to show how the route can be successfully called.

    Testing With a Token From FusionAuth

    To access the secured lambda function, we’ll need to get a valid token. Normally, your frontend app would use the Authorization Code grant which would redirect a user to FusionAuth to login, obtain a code, and then exchange that code for a token, using a framework of your choice. More on the Authorization Code grant.

    For the purposes of this guide, we’ll call the FusionAuth Login API on behalf of a user to create a token directly. This is a more straightforward means of getting a token, but the generated token will be similar with either process.

    To use the Login API, there are a few settings that need to be changed on FusionAuth. In the side panel in FusionAuth, select Settings > API Keys. Click the green + button at the top left to create a new key.

    Give the key a meaningful description, like API Gateway Key. Select the Tenant that you created the FusionAuth application under (normally Default).

    Then, under Endpoints, allow POST on the /api/login route. This key will only be allowed to call this endpoint with the POST method.

    Enabling the login API

    Save the API key. You should now see a list of all API keys. Click on the lock icon next to the key field for the key you just created and copy the API key for later use. Make sure you get the API key value and not the API key Id.

    Enabling the login API

    To test, you’ll need to link a FusionAuth user to your application. You can either use the existing admin user you use to log into FusionAuth or create a new isolated user.

    To link your existing user, navigate to the user list through the Users menu item in the sidebar. Find your user and click the Manage action button on the user. Click the Registrations tab. Click Add registrations and select the FusionAuth application you set up earlier.

    Alternatively, to create a new user, navigate to Users in the sidebar and click the green + button at the top right of the screen to create a new user. Choose the appropriate tenant (usually default) and fill in the information. You can choose not to send an email to set up the password but rather set it directly when creating the user by toggling the Send email to set up password switch. Record this user email and password, as we’ll use it to obtain a token.

    After saving the user, click the Registrations tab. Click Add registrations and select the FusionAuth application you set up earlier.

    The application registrations tab

    Using curl or Postman, make a POST request to your FusionAuth instance’s /api/login endpoint. This will return a JWT in the response.

    The curl call should look like this:

    curl command to obtain a JWT token
    
    curl --location --request POST 'https://<YOUR_FUSIONAUTH_URL>/api/login' \
    --header 'Authorization: <API_KEY>' \
    --header 'Content-Type: application/json' \
    --data-raw '  {
        "loginId": "<USER_EMAIL>",
        "password": "<USER_PASSWORD>",
        "applicationId": "<APPLICATION_ID>",
        "noJWT" : false
      }'

    Where:

    • <YOUR_FUSIONAUTH_URL> is the URL of your FusionAuth installation.

    • <API_KEY> is the API key created above, enabled for login.

    • <USER_EMAIL> is the email address of the user added above.

    • <USER_PASSWORD> is the password of the user added above.

    • <APPLICATION_ID> is the Id of the FusionAuth application registered for the user.

    The return response from FusionAuth should look similar to the following:

    Login API Response
    
    {
        "token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImhDUjA4X3daR2s0OUFlYUFmRDY5ZmJKWmRGTSJ9.eyJhdWQiOiI2M2I3M2Y3Ni03NDAwLTQ4N2QtYjEyMi01NzA1Yjg0OGRhODAiLCJleHAiOjE2NzMzNjYyMDQsImlhdCI6MTY3MzM2MjYwNCwiaXNzIjoiaHR0cHM6Ly9mdXNpb25hdXRoLnJpdHphLmNvIiwic3ViIjoiMzk2MzAwMGYtNjg2ZC00MTY5LWI2MjgtOWM5YzQ1MzRiNzgwIiwianRpIjoiZDk3ZGIyZWYtZjExNS00ZDIxLWFlOTQtMDIyN2RmMGU4YzI5IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6ImJvYkBhd3MuY29tIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsInByZWZlcnJlZF91c2VybmFtZSI6ImJvYmF3cyIsImFwcGxpY2F0aW9uSWQiOiI2M2I3M2Y3Ni03NDAwLTQ4N2QtYjEyMi01NzA1Yjg0OGRhODAiLCJyb2xlcyI6W10sImF1dGhfdGltZSI6MTY3MzM2MjYwNCwidGlkIjoiZjAwNGMxZmUtNDg0Yi05MDJjLWQ3Y2EtYmRiYzQ2NGRhMGI3In0.m7gzXhNLToPNVE1p5Vo2pLgP6WBcPNfS_zZJnJ81mdEgi6-orViz-tU8j0L8wva0-8KlMdy54cq_XjnDnYJ0aX90O4ZE_QVU5NuDDfzXH14wQtKQoIIydsB6ZvQoBt8JNFUHJb9ANLCGnfn6FVQKqPIzye18Gx_7wYSVokw3eLNFyzrq9dwOD5Q8V9gvZmXV2pTokQAtA7qFaadb2dIeFlSEB7wamKiZLXILjeWAeMbbvAAMQZWFh46UJjwr06QTd8PxQmRwDWWznJy1Vs8EAgZA4vkRSWnn3IbiaCtOaL1ANuEex6il7q32ahxj0Ncm9wn0DbDsQE9NB0CCNTSIhA",
        "tokenExpirationInstant": 1673366204805,
        "user": {
          "sampleuserdata" : "..."
        }
    }

    Copy the token value. This is a JWT, which we can use to access the API gateway function.

    Now call the API gateway with the following curl command:

    Calling the API Gateway endpoint with the JWT
    
    curl --location --request GET 'https://<GATEWAY_URL>/privateFunction' \
    --header 'Authorization: Bearer <JWT_TOKEN>'

    Where:

    • <GATEWAY_URL> is the invoke URL saved earlier.

    • <JWT_TOKEN> is the JWT from the /api/login call.

    You should see the function return with a reflection of the claims it received:

    Return token from the API call
    
    {
        "applicationId":"63b73f76-7400-487d-b122-5705b848da80",
        "aud":"63b73f76-7400-487d-b122-5705b848da80",
        "auth_time":"1672137288",
        "authenticationType":"PASSWORD",
        "email":"ehrlich@piedpiper.com",
        "email_verified":"true",
        "exp":"1672140888",
        "iat":"1672137288",
        "iss":"https://local.fusionauth.io",
        "jti":"2f80b975-1870-4970-b876-90c2e7d9444b",
        "preferred_username":"erlich",
        "roles":"[]",
        "sub":"3963000f-686d-4169-b628-9c9c4534b780",
        "tid":"f004c1fe-484b-902c-d7ca-bdbc464da0b7"
     }

    Troubleshooting

    • If you are running a local instance of FusionAuth, Amazon API Gateway will not be able to reach the key sets needed to validate the JWT. You will either need to host FusionAuth on a publicly accessible URL or proxy your local instance through a tool like ngrok.

    • Ensure that your FusionAuth application’s Access Token signing key and Id Token signing key on the application’s JWT tab are asymmetric (RS256).

    • The JWT issued by the FusionAuth Login API has an expiry. If you wait too long before using it to call the Amazon API Gateway, the token will expire and the call will fail. You can resolve this by re-running the curl command to obtain a JWT token and using the new token.

    Next Steps

    You can build a complete HTTP API using Amazon API Gateway, AWS Lambda, and FusionAuth without managing any servers.

    You can also configure required scopes for a route and check against them before allowing a user through. Set the scope claim using a JWT Populate lambda.

    Finally, you can configure FusionAuth to ensure that the user is registered for the Amazon Gateway API application or fire off webhooks when the user logs in.

    Feedback

    How helpful was this page?

    See a problem?

    File an issue in our docs repo

    Have a question or comment to share?

    Visit the FusionAuth community forum.

    © 2023 FusionAuth
    How-to
    Blog
    Expert Advice
    Download
    Subscribe for developer updates