You are browsing unreleased documentation. See the latest documentation here.
Allowing Multiple Authentication Methods
The default behavior for Kong authentication plugins is to require credentials for all requests without regard for whether a request has been authenticated via some other plugin. Configuring an anonymous consumer on your authentication plugins allows you to offer clients multiple options for authentication.
Set up consumers
To begin, create a service, then create three consumers:
- Consumer 1:
curl -sX POST localhost:8001/consumers \ -H "Content-Type: application/json" \ --data '{"username": "anonymous"}'
Response:
{"created_at":1517528237000,"username":"anonymous","id":"d955c0cb-1a6e-4152-9440-414ebb8fee8a"}
The
anonymous
consumer does not correspond to any real user, and will only serve as a fallback. - Consumer 2:
curl -sX POST localhost:8001/consumers \ -H "Content-Type: application/json" \ --data '{"username": "medvezhonok"}'
Response:
{"created_at":1517528259000,"username":"medvezhonok","id":"b3c95318-a932-4bb2-9d74-1298a3ffc87c"}
-
Consumer 3:
curl -sX POST localhost:8001/consumers \ -H "Content-Type: application/json" \ --data '{"username": "ezhik"}'
Response:
{"created_at":1517528266000,"username":"ezhik","id":"47e74a17-dc08-4786-a8cf-d8e4f38a5459"}
Set up authentication plugins
Next, we add both Key Auth and Basic Auth plugins to our service, and set the anonymous fallback to the consumer we created earlier.
-
Add the Key Auth plugin:
curl -sX POST localhost:8001/services/example-service/plugins/ \ -H "Content-Type: application/json" \ --data '{"name": "key-auth", "config": { "hide_credentials": true, "anonymous": "d955c0cb-1a6e-4152-9440-414ebb8fee8a"} }'
Response:
{"created_at":1517528304000,"config":{"key_in_body":false,"hide_credentials":true,"anonymous":"d955c0cb-1a6e-4152-9440-414ebb8fee8a","run_on_preflight":true,"key_names":["apikey"]},"id":"bb884f7b-4e48-4166-8c80-c858b5a4c357","name":"key-auth","service_id":"a2a168a8-4491-4fe1-9426-cde3b5fcd45b","enabled":true}
-
Add the Basic Auth plugin:
curl -sX POST localhost:8001/services/example-service/plugins/ \ -H "Content-Type: application/json" \ --data '{"name": "basic-auth", "config": { "hide_credentials": true, "anonymous": "d955c0cb-1a6e-4152-9440-414ebb8fee8a"} }'
Response:
{"created_at":1517528499000,"config":{"hide_credentials":true,"anonymous":"d955c0cb-1a6e-4152-9440-414ebb8fee8a"},"id":"e5a40543-debe-4225-a879-a54901368e6d","name":"basic-auth","service_id":"a2a168a8-4491-4fe1-9426-cde3b5fcd45b","enabled":true}
If using OpenID Connect, you must also set config.consumer_claim
along with anonymous
, as setting anonymous
alone will not map that consumer.
Test with anonymous consumer
At this point, unauthenticated requests and requests with invalid credentials are still allowed. The anonymous consumer is allowed, and will be applied to any request that does not pass a set of credentials associated with some other consumer.
-
Check without credentials:
curl -s example.com:8000/user-agent
Response:
{"user-agent": "curl/7.58.0"}
-
Check with nonsense credentials:
curl -s example.com:8000/user-agent?apikey=nonsense
Response:
{"user-agent": "curl/7.58.0"}
Configure credentials
We’ll now add a Key Auth credential for one consumer, and a Basic Auth credential for another.
- Add a Basic Auth credential to one consumer:
curl -sX POST localhost:8001/consumers/medvezhonok/basic-auth \ -H "Content-Type: application/json" \ --data '{"username": "medvezhonok", "password": "hunter2"}'
Response:
{"created_at":1517528647000,"id":"bb350b87-f0d2-4605-b997-e28a116d8b6d","username":"medvezhonok","password":"f239a0404351d7170201e7f92fa9b3159e47bb01","consumer_id":"b3c95318-a932-4bb2-9d74-1298a3ffc87c"}
- Add a Key Auth credential to another consumer:
curl -sX POST localhost:8001/consumers/ezhik/key-auth \ -H "Content-Type: application/json" \ --data '{"key": "hunter3"}'
Response:
{"id":"06412d6e-8d41-47f7-a911-3c821ec98f1b","created_at":1517528730000,"key":"hunter3","consumer_id":"47e74a17-dc08-4786-a8cf-d8e4f38a5459"}
-
Lastly, add a Request Terminator to the anonymous consumer:
curl -sX POST localhost:8001/consumers/d955c0cb-1a6e-4152-9440-414ebb8fee8a/plugins/ \ -H "Content-Type: application/json" \ --data '{"name": "request-termination", "config": { "status_code": 401, "content_type": "application/json; charset=utf-8", "body": "{\"error\": \"Authentication required\"}"} }'
Response:
{"created_at":1517528791000,"config":{"status_code":401,"content_type":"application\/json; charset=utf-8","body":"{\"error\": \"Authentication required\"}"},"id":"21fc5f6f-363f-4d79-b533-ce26d4478879","name":"request-termination","enabled":true,"consumer_id":"d955c0cb-1a6e-4152-9440-414ebb8fee8a"}
Validate credentials
Validate one more time. Requests with missing or invalid credentials are now rejected, whereas authorized requests using either authentication method are allowed.
-
Test with a nonsense API key:
curl -s localhost:8000/user-agent?apikey=nonsense
Response:
{"error": "Authentication required"}
- Test without an API key:
curl -s localhost:8000/user-agent
Response:
{"error": "Authentication required"}
-
Test with the configured API key:
curl -s localhost:8000/user-agent?apikey=hunter3
Response:
{"user-agent": "curl/7.58.0"}
- Test with the configured basic auth credentials:
curl -s localhost:8000/user-agent -u medvezhonok:hunter2
Response:
{"user-agent": "curl/7.58.0"}