Authentication
Learn to configure multiple authentication options for consumers using the Kong Ingress Controller.
The default behavior for Kong authentication plugins is to require credentials for all requests even if a request has been authenticated through another plugin. Configure an anonymous consumer on your authentication plugins to set clients authentication options.
Before you begin ensure that you have Installed Kong Ingress Controller with Gateway API support in your Kubernetes cluster and are able to connect to Kong.
Before you begin ensure that you have Installed Kong Ingress Controller with Gateway API support in your Kubernetes cluster and are able to connect to Kong.
Prerequisites
Install the Gateway APIs
-
Install the Gateway API CRDs before installing Kong Ingress Controller.
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.1.0/standard-install.yaml
-
Create a
Gateway
andGatewayClass
instance to use.echo " --- apiVersion: gateway.networking.k8s.io/v1 kind: GatewayClass metadata: name: kong annotations: konghq.com/gatewayclass-unmanaged: 'true' spec: controllerName: konghq.com/kic-gateway-controller --- apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: kong spec: gatewayClassName: kong listeners: - name: proxy port: 80 protocol: HTTP " | kubectl apply -f -
The results should look like this:
gatewayclass.gateway.networking.k8s.io/kong created gateway.gateway.networking.k8s.io/kong created
Install Kong
You can install Kong in your Kubernetes cluster using Helm.
-
Add the Kong Helm charts:
helm repo add kong https://charts.konghq.com helm repo update
-
Install Kong Ingress Controller and Kong Gateway with Helm:
helm install kong kong/ingress -n kong --create-namespace
Test connectivity to Kong
Kubernetes exposes the proxy through a Kubernetes service. Run the following commands to store the load balancer IP address in a variable named PROXY_IP
:
-
Populate
$PROXY_IP
for future commands:export PROXY_IP=$(kubectl get svc --namespace kong kong-gateway-proxy -o jsonpath='{.status.loadBalancer.ingress[0].ip}') echo $PROXY_IP
-
Ensure that you can call the proxy IP:
curl -i $PROXY_IP
The results should look like this:
HTTP/1.1 404 Not Found Content-Type: application/json; charset=utf-8 Connection: keep-alive Content-Length: 48 X-Kong-Response-Latency: 0 Server: kong/3.0.0 {"message":"no Route matched with those values"}
Deploy an upstream HTTP application
Create a Kubernetes service setup a httpbin service in the cluster and proxy it.
kubectl apply -f https://docs.konghq.com/assets/kubernetes-ingress-controller/examples/httpbin-service.yaml
The results should look like this:
service/httpbin created
deployment.apps/httpbin created
The results should look like this:
Create Consumers and secrets
Create two consumers that use different authentication methods:
-
consumer-1
usesbasic-auth
-
consumer-2
useskey-auth
-
Create a secret to add
basic-auth
credential forconsumer-1
.echo ' apiVersion: v1 kind: Secret metadata: name: consumer-1-basic-auth labels: konghq.com/credential: basic-auth stringData: username: consumer-1 password: consumer-1-password ' | kubectl apply -f -
The results should look like this:
secret/consumer-1-basic-auth created
-
Create a consumer named
consumer-1
.echo "apiVersion: configuration.konghq.com/v1 kind: KongConsumer metadata: name: consumer-1 annotations: kubernetes.io/ingress.class: kong username: consumer-1 credentials: - consumer-1-basic-auth " | kubectl apply -f -
The results should look like this:
kongconsumer.configuration.konghq.com/consumer-1 created
-
Create a secret to add
key-auth
credential forconsumer-2
.echo ' apiVersion: v1 kind: Secret metadata: name: consumer-2-key-auth labels: konghq.com/credential: key-auth stringData: key: consumer-2-password ' | kubectl apply -f -
The results should look like this:
secret/consumer-2-key-auth created
-
Create a consumer named
consumer-2
.echo "apiVersion: configuration.konghq.com/v1 kind: KongConsumer metadata: name: consumer-2 annotations: kubernetes.io/ingress.class: kong username: consumer-2 credentials: - consumer-2-key-auth " | kubectl apply -f -
The results should look like this:
kongconsumer.configuration.konghq.com/consumer-2 created
Secure the Ingress
-
Create two plugins.
- Create a plugin named
httpbin-basic-auth
.
echo ' apiVersion: configuration.konghq.com/v1 kind: KongPlugin metadata: name: httpbin-basic-auth config: anonymous: anonymous hide_credentials: true plugin: basic-auth ' | kubectl apply -f -
The results should look like this:
kongplugin.configuration.konghq.com/httpbin-basic-auth created
- Create a plugin named
httpbin-key-auth
.
echo ' apiVersion: configuration.konghq.com/v1 kind: KongPlugin metadata: name: httpbin-key-auth config: key_names: - apikey anonymous: anonymous hide_credentials: true plugin: key-auth ' | kubectl apply -f -
The results should look like this:
kongplugin.configuration.konghq.com/httpbin-key-auth created
- Create a plugin named
-
Associate the plugins with the route that you created.
Anonymous Consumers
Your endpoints are now secure, but neither consumer can access the endpoint when providing valid credentials. This is because each plugin will verify the consumer using it’s own authentication method.
To allow multiple authentication methods, create an anonymous consumer which is the default user if no valid credentials are provided:
-
Create a consumer named
anonymous
.echo "apiVersion: configuration.konghq.com/v1 kind: KongConsumer metadata: name: anonymous annotations: kubernetes.io/ingress.class: kong username: anonymous " | kubectl apply -f -
The results should look like this:
kongconsumer.configuration.konghq.com/anonymous created
All requests to the API will now succeed as the anonymous consumer is being used as a default.
To secure the API once again, add a request termination plugin to the anonymous consumer that returns
HTTP 401
: -
Create a
Request Termination
plugin.echo ' apiVersion: configuration.konghq.com/v1 kind: KongPlugin metadata: name: anonymous-request-termination config: message: "Authentication required" status_code: 401 plugin: request-termination ' | kubectl apply -f -
The results should look like this:
kongplugin.configuration.konghq.com/anonymous-request-termination created
-
Associate the
Request Termination
plugin to theanonymous
consumer.echo ' apiVersion: configuration.konghq.com/v1 kind: KongConsumer metadata: annotations: konghq.com/plugins: anonymous-request-termination kubernetes.io/ingress.class: kong name: anonymous username: anonymous ' | kubectl apply -f -
The results should look like this:
kongconsumer.configuration.konghq.com/anonymous configured
Test the configuration
Any requests with missing or invalid credentials are rejected, whereas authorized requests using either of the authentication methods are allowed.
- Send a request with invalid credentials.
curl -i $PROXY_IP/test/status/200 -H apikey:invalid
The results should look like this:
HTTP/1.1 401 Unauthorized Content-Type: application/json; charset=utf-8 Connection: keep-alive WWW-Authenticate: Key realm="kong" Content-Length: 37 X-Kong-Response-Latency: 3 Server: kong/3.3.1 {"message":"Authentication required"}%
- Send a request without any credentials.
curl -i $PROXY_IP/test/status/200
The results should look like this:
HTTP/1.1 401 Unauthorized Content-Type: application/json; charset=utf-8 Connection: keep-alive WWW-Authenticate: Key realm="kong" Content-Length: 37 X-Kong-Response-Latency: 1 Server: kong/3.3.1 {"message":"Authentication required"}%
- Send a request using the
basic-auth
authentication methodcurl -i $PROXY_IP/test/status/200 -u consumer-1:consumer-1-password
The results should look like this:
HTTP/1.1 200 OK Content-Type: text/html; charset=utf-8 Content-Length: 0 Connection: keep-alive WWW-Authenticate: Key realm="kong" Server: gunicorn/19.9.0 Access-Control-Allow-Origin: * Access-Control-Allow-Credentials: true X-Kong-Upstream-Latency: 1309 X-Kong-Proxy-Latency: 3 Via: kong/3.3.1
- Send a request using the
key-auth
authentication methodcurl -i $PROXY_IP/test/status/200 -H apikey:consumer-2-password
The results should look like this:
HTTP/1.1 200 OK Content-Type: text/html; charset=utf-8 Content-Length: 0 Connection: keep-alive Server: gunicorn/19.9.0 Access-Control-Allow-Origin: * Access-Control-Allow-Credentials: true X-Kong-Upstream-Latency: 1227 X-Kong-Proxy-Latency: 4 Via: kong/3.3.1