Skip to content

Instantly share code, notes, and snippets.

@fsargent
Last active February 17, 2024 15:07
Show Gist options
  • Save fsargent/47b9bc678ab197a62ce5a186f67e269e to your computer and use it in GitHub Desktop.
Save fsargent/47b9bc678ab197a62ce5a186f67e269e to your computer and use it in GitHub Desktop.
JWT Validation with Auth0 and Kong

To get setup with Auth0 and Kong.

Kong is pretty cool. Auth0 is pretty cool. They should work together. This guide details the fastest way to get your APIs protected using JWT tokens issued by Auth0.

Pre-requisites:

  • Create a Auth0 account. Account name is referred to "COMPANYNAME" for the sake of the guide.
  • Setup a Kong instance on your machine. This guide assumes a brand new blank instance.
  • Install httpie - a http command line utility built for humans (unlike curl).
  1. Create API $ http POST :8001/apis name=example-api hosts=example.com upstream_url=http://httpbin.org

  2. Add JWT Plugin $ http POST :8001/apis/example-api/plugins name=jwt

  3. Download your Auth0 account's Certificate $ http https://COMPANYNAME.auth0.com/pem --download

  4. Transform the Certificate into a public key. $ openssl x509 -pubkey -noout -in COMPANYNAME.pem > pubkey.pem

  5. Create a consumer with the Auth0 public key $ http post :8001/consumers/adama/jwt algorithm=RS256 rsa_public_key@./pubkey.pem key=https://COMPANYNAME.auth0.com/ -f

  6. Success! Send requests through, only valid tokens will work. $ http GET :8000 Host:example.com Authorization:"Bearer {{TOKEN}}" -v

Wow, that looked so simple, why did you write an article about this?

Becuase this is incredibly hard. Alternative solutions to kong involve:

Integrating your middleware direcly into your codebase. This is hell if you have many APIs. Even worse, you have to audit each library for each programming language. Errors in these libraries are common, and become fatal security holes.

OR

Running a odd custom version of Nginx that supports LUA (https://github.com/auth0/nginx-jwt). Or signing up for Nginx-Plus.

@martinjras
Copy link

Thank you. Looks great :)

@somada141
Copy link

Took me a while to figure it out but just in case anybody tries to do the above with the declarative YAML syntax the kong.yml should look like this:

services:
  - name: my-awesome-service
    url: "https://jsonplaceholder.typicode.com/users"
    routes:
      - name: users
        paths:
          - /users
    plugins:
      - name: jwt

consumers:
  - username: "my_consumer_username"

jwt_secrets:
  - consumer: "my_consumer_username"
    key: "https://COMPANYNAME.auth0.com/"
    algorithm: "RS256"
    rsa_public_key: |-
      -----BEGIN PUBLIC KEY-----
      bunch of letters and numbers
      spread over
      multiple lines
      -----END PUBLIC KEY-----

Do note that the Kong v1.3 seems to be having issues with the above as detailed under Kong/kong#4954. Try v1.2 if you're having errors like the one stated in the issue.

@linuxbandit
Copy link

Rewritten for Kong 2.x, correcting a new Auth0 URL, and adding point @jlsumler mentioned:

http POST :8001/services name=example-api  url=http://httpbin.org

http POST :8001/services/example-api/routes hosts:='["example.com"]'

http POST :8001/services/example-api/plugins name=jwt

http https://COMPANYNAME.REGION.auth0.com/pem --download    # REGION is 'eu' if servers in Europe, etc

http POST :8001/consumers username=adama

http post :8001/consumers/adama/jwt algorithm=RS256 rsa_public_key@./pubkey.pem key=https://COMPANYNAME.REGION.auth0.com/ -f

How do I get the TOKEN is still unclear to me though, any hint @fsargent?

@kiwiidb
Copy link

kiwiidb commented Oct 4, 2020

Does this also work with Firebase tokens, as explained here https://firebase.google.com/docs/auth/admin/verify-id-tokens ?

@james-bowen-au
Copy link

james-bowen-au commented Jan 31, 2021

Rewritten for Kong 2.x, correcting a new Auth0 URL, and adding point @jlsumler mentioned:

http POST :8001/services name=example-api  url=http://httpbin.org

http POST :8001/services/example-api/routes hosts:='["example.com"]'

http POST :8001/services/example-api/plugins name=jwt

http https://COMPANYNAME.REGION.auth0.com/pem --download    # REGION is 'eu' if servers in Europe, etc

http POST :8001/consumers username=adama

http post :8001/consumers/adama/jwt algorithm=RS256 rsa_public_key@./pubkey.pem key=https://COMPANYNAME.REGION.auth0.com/ -f

How do I get the TOKEN is still unclear to me though, any hint @fsargent?

If anyone is still wondering how to do this - (and you're happy to just use the default as an experiment) etc..

  1. Follow https://auth0.com/docs/get-started
  2. Create a tenant, then an application (use machine to machine)
  3. Use the quick start app and get the auth url.
  4. Use that url to authenticate
  5. Grab the token from the response and assign to an environment variable called TOKEN as per the tutorial.
  6. Submit curl/httpie request and you should get through to the httpbin.org endpoint again.

Select_API

App_Success

Authorise_Machine_Machine

Create_Application

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment