Allow clients to choose their authentication methods and prevent unauthorized access

Uses: Kong Gateway decK
Related Resources
Minimum Version
Kong Gateway - 3.4
TL;DR

Configure multiple authentication plugins, like Key Auth and Basic Auth, and apply them to specific Consumers. Set config.anonymous in those plugins to the ID of the anonymous Consumer to catch access attempts from anyone else. Then, apply the Request Termination plugin to the anonymous Consumer to terminate the requests and send back a specific message.

Prerequisites

This is a Konnect tutorial and requires a Konnect personal access token.

  1. Create a new personal access token by opening the Konnect PAT page and selecting Generate Token.

  2. Export your token to an environment variable:

     export KONNECT_TOKEN='YOUR_KONNECT_PAT'
    
    Copied to clipboard!
  3. Run the quickstart script to automatically provision a Control Plane and Data Plane, and configure your environment:

     curl -Ls https://get.konghq.com/quickstart | bash -s -- -k $KONNECT_TOKEN --deck-output
    
    Copied to clipboard!

    This sets up a Konnect Control Plane named quickstart, provisions a local Data Plane, and prints out the following environment variable exports:

     export DECK_KONNECT_TOKEN=$KONNECT_TOKEN
     export DECK_KONNECT_CONTROL_PLANE_NAME=quickstart
     export KONNECT_CONTROL_PLANE_URL=https://us.api.konghq.com
     export KONNECT_PROXY_URL='http://localhost:8000'
    
    Copied to clipboard!

    Copy and paste these into your terminal to configure your session.

Create Consumers

You can use multiple authentication plugins with an anonymous Consumer to give clients multiple options for authentication. The anonymous Consumer doesn’t correspond to any real user, and acts as a fallback to catch all other unauthorized requests.

Create three Consumers, including the anonymous Consumer:

echo '
_format_version: "3.0"
consumers:
  - username: anonymous
  - username: Dana
  - username: Mahan
' | deck gateway apply -
Copied to clipboard!

We’re going to assign a different authentication type to each Consumer later.

Set up authentication

Add the Key Auth and Basic Auth plugins to the example-service Gateway Service, and set the anonymous fallback to the Consumer we created earlier:

echo '
_format_version: "3.0"
plugins:
  - name: key-auth
    service: example-service
    config:
      hide_credentials: true
      anonymous: anonymous
  - name: basic-auth
    service: example-service
    config:
      hide_credentials: true
      anonymous: anonymous
' | deck gateway apply -
Copied to clipboard!

Test with anonymous Consumer

You now have authentication enabled on the Gateway Service, but the anonymous Consumer also allows requests from unauthenticated clients.

The following validation works because the unauthenticated request falls back to the anonymous Consumer, which allows it through:

curl -i "$KONNECT_PROXY_URL/anything"
Copied to clipboard!

The following validation with fake credentials also works because an incorrect API key is treated as anonymous:

curl -i "$KONNECT_PROXY_URL/anything" \
     -H "apikey:nonsense"
Copied to clipboard!

In both cases, you should get a 200 response, as the anonymous Consumer is allowed.

Configure credentials

Now, let’s configure Consumers with different auth credentials and prevent unauthenticated access. Configure different credentials for the two named users: basic auth for Dana, and key auth for Mahan:

echo '
_format_version: "3.0"
consumers:
  - username: Dana
    basicauth_credentials:
    - username: Dana
      password: dana
  - username: Mahan
    keyauth_credentials:
    - key: mahan
' | deck gateway apply -
Copied to clipboard!

Add Request Termination to the anonymous Consumer

The anonymous Consumer gets no credentials, as we don’t want unauthenticated users accessing our Gateway Service. Instead, you can configure the Request Termination plugin to handle anonymous Consumers and redirect their requests with a 401:

echo '
_format_version: "3.0"
consumers:
  - username: anonymous
    plugins:
    - name: request-termination
      config:
        status_code: 401
        message: '"Error - Authentication required"'
' | deck gateway apply -
Copied to clipboard!

Validate authentication

Let’s check that authentication works.

Try to access the Gateway Service via the /anything Route using a nonsense API key:

curl -i "$KONNECT_PROXY_URL/anything" \
     -H "apikey:nonsense"
Copied to clipboard!

The request should now fail with a 401 response and your configured error message, as this Consumer is considered anonymous.

You should get the same result if you try to access the Route without any API key:

curl -i "$KONNECT_PROXY_URL/anything"
Copied to clipboard!

Finally, try accessing the Route with the configured basic auth credentials:

curl -i "$KONNECT_PROXY_URL/anything" \
     -u Dana:dana
Copied to clipboard!

This time, authentication should succeed with a 200.

Cleanup

If you created a new control plane and want to conserve your free trial credits or avoid unnecessary charges, delete the new control plane used in this tutorial.

FAQs

Did this doc help?

Something wrong?

Help us make these docs great!

Kong Developer docs are open source. If you find these useful and want to make them better, contribute today!