This demo shows how to protect an API using Kong API Gateway and auth0. It requires Docker to run.
It consists of three components:
- A static frontend written in React
- A Node.js/Express backend
- A Kong API Gateway to connect the two
Once configured, you can start the application using Docker
docker compose up --build
This will start the three Docker containers. You'll be able to connect to these endpoints:
- http://localhost:3000/ - The React frontend application
- http://localhost:4000/api/ - The Kong API Gateway
- http://localhost:8000/api/ - The actual backend behind the Kong API. In a real-world scenario, you would only allow connections from the API Gateway
You can use the Postman Collection to play around with the endpoint.
For example, try http://localhost:4000/api/ and http://localhost:4000/api/protected/ to see the difference between protected and unprotected endpoints.
There are a few steps to configure but the whole process will take less than 10 minutes start to finish. :)
We use auth0 simply because they provides a free developer account. Since OAuth 2.0 is standardized, this example can easily made to work with most other SSO Providers like Azure AD.
If you haven't done already, go to https://auth0.com/signup to register an free developer account
- When asked for "Account Type", select "Other"
- Tick the "I need advanced settings" box
- When asked for "Tenant Domain", pick a new subdomain or use the one generated by auth0. This is your tenant and the domain that the users will be redirected to when they initiate a login.
- Select the applicable region (most likely: "EU")
After creating the account and logging in, create a new SPA application
-
Click "Applications" on the left hand side to open the Applications view
-
Click "Applications" to view all current applications - you should have at least one: the "Default App"
-
Select "Create Application"
-
Give the app a name (e.g., "Kong Demo App")
-
Select "Single Page Web Applications"
-
In the application settings, find the "Domain" and the "Client ID"
-
Rename the file
src/frontend/.env-template
tosrc/frontend/.env
and copy the "Domain" and the "Client ID" to the respective fields:# src/frontend/.env VITE_REACT_APP_AUTH0_DOMAIN=kong-api-demo.eu.auth0.com VITE_REACT_APP_AUTH0_CLIENT_ID=TvSR...MX4z VITE_REACT_APP_AUTH0_CALLBACK_URL=http://localhost:3000/ VITE_REACT_APP_AUTH0_AUDIENCE=http://localhost:4000/ VITE_BACKEND_API_ORIGIN=http://localhost:4000/
-
In the application settings, scroll down to Application URIs and copy the
VITE_REACT_APP_AUTH0_CALLBACK_URL
from the file above into the "Allowed Callback URLs", "Allowed Logout URLs", and "Allowed Web Origins". By default, this will be http://localhost:3000/, but you can change this in thedocker-compose.yml
file.
This concludes the steps necessary for authentication (login). Read on to configure authorization (roles).
- Click "Applications" on the left hand side to open the Applications view
- Click "API" to view all current APIs - you should have at least one: the "Auth0 Management API"
- Click on "Create API"
- Give the API a name (e.g., "Kong Demo API")
- For the "Identifier", take the
VITE_REACT_APP_AUTH0_AUDIENCE
from thesrc/frontend/.env
created above. The default is http://localhost:4000/. You can pick any value, but you will not be able to change it later. - Click "Create" to create the API
- In the settings, scroll down to "RBAC Setting" and enable "Enable RBAC" and "Add Permissions in the Access token".
- Click on "Permissions" and add some permissions
- Under "Permission" give a string like "read", "write", or "admin"
- Under "Description" select an appropriate name for this permission
- Click "User Management" on the left hand side
- Click "Users"
- Click "Add users" and fill out the user information. You can user an "@example.com"-Email or any other email that is NOT the one from your auth0 user.
- Give the user a name and a password.
- Click "Create"
- In the "Details" of the user, click on "Permissions"
- Click on "Assign Permissions"
- Select the API created in the previous step. This will bring up a list of all permissions you have created. Select at least one and click "Add Permissions"
Kong provides a JWT plugin to handle the verification of JWTs. Once configured, only access tokens signed by the authentication server are allowed to access a certain route.
The plugin needs two pieces of information that are not obvious to configure: a rsa_public_key
(aka the "signing certificate") and a key
(aka the identifier of the "signing certificate"). Both information are provided by the authentication platform in their JSON Web Key Set. The location of the JWKS depends on the provider and is often published in the .well-known/openid-configuration
endpoint. In our example (auth0), the location is https://<TENANT_NAME>.<REGION_ID>.auth0.com/.well-known/jwks.json
.
auth0 provides access to both the key
and the rsa_public_key
in their dashboard under ["Settings" > "Signing Keys"]. Under "List of Valid Keys", find the "Currently used" key. The "Key ID" is the value we are going to use as key
. Click on the three dots on the right and "Download Signing Certificate".
The signing certificate is most likely a "x509 certificate" from which we need to extract the public key, first.
Hint: the following example works on Linux and macOS - Windows users might need to install
openssl
separately.
# Extract the public keys to a new file
openssl x509 -pubkey -noout -in <SIGNING_CERTIFICATE>.pem > pubkey.pem
Then, copy the public key to the Kong configuration.
Important: Make sure the key itself is in one line without any newlines and the indentation is correct. Otherwise, Kong will throw an error.
# src/api_gateway/.docker/kong/declarative/api_gateway.yml
---
jwt_secrets:
- consumer: auth0
secret: this-is-a-dummy-value
algorithm: RS256
key: dqVeGigzuTz-IF0V63ZmB
rsa_public_key: |
-----BEGIN PUBLIC KEY-----
MIIBIj...AQAB
-----END PUBLIC KEY-----
- auth0 Quickstarts: https://auth0.com/docs/quickstart/
provide easy-to-follow instructions to set up different authentication scenarios with different frameworks.
-
Find the "Open ID Configuration" for the provider.
For example, Azure publishes these at https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration. -
Find the "jwks_uri" in the "Open ID Configuration".
In the example above, that is https://login.microsoftonline.com/common/discovery/v2.0/keys. -
The response will most likely contain more than one key. Look for the "Key ID" or "KID" of your application. Find the corresponding entry under "x5c". This string is your "signing certificate".
-
Either copy the certificate to a file and use
openssl
as described above or copy it to a pem-to-jwk convert (e.g., https://irrte.ch/jwt-js-decode/pem2jwk.html) to extract the public key -
Use the result as described above