multi-auth
The multi-auth plugin allows consumers using different authentication methods to share the same route or service. It supports the configuration of multiple authentication plugins, so that a request is allowed through if it authenticates successfully against any configured method.
Examples
Allow Different Authentications on the Same Route
The following example demonstrates how to have one consumer using basic authentication, while another consumer using key authentication, both sharing the same route.
- Admin API
- ADC
- Ingress Controller
Create two consumers:
curl "http://127.0.0.1:9180/apisix/admin/consumers" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"username":"consumer1"
}'
curl "http://127.0.0.1:9180/apisix/admin/consumers" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"username":"consumer2"
}'
Configure basic authentication credential for consumer1:
curl "http://127.0.0.1:9180/apisix/admin/consumers/consumer1/credentials" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "cred-jane-key-auth",
"plugins": {
"basic-auth": {
"username":"consumer1",
"password":"consumer1_pwd"
}
}
}'
Configure key authentication credential for consumer2:
curl "http://127.0.0.1:9180/apisix/admin/consumers/consumer2/credentials" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "cred-jane-key-auth",
"plugins": {
"key-auth": {
"key":"consumer2_pwd"
}
}
}'
Create a route with multi-auth and configure the two authentication plugins that consumers use:
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "multi-auth-route",
"uri": "/anything",
"plugins": {
"multi-auth":{
"auth_plugins":[
{
"basic-auth":{}
},
{
"key-auth":{
"hide_credentials":true,
"header":"apikey",
"query":"apikey"
}
}
]
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org": 1
}
}
}'
Create two consumers with their respective credentials and a route with multi-auth:
consumers:
- username: consumer1
credentials:
- name: cred-consumer1-basic-auth
type: basic-auth
config:
username: consumer1
password: consumer1_pwd
- username: consumer2
credentials:
- name: cred-consumer2-key-auth
type: key-auth
config:
key: consumer2_pwd
services:
- name: multi-auth-service
routes:
- name: multi-auth-route
uris:
- /anything
plugins:
multi-auth:
auth_plugins:
- basic-auth: {}
- key-auth:
hide_credentials: true
header: apikey
query: apikey
upstream:
type: roundrobin
nodes:
- host: httpbin.org
port: 80
weight: 1
Preview the changes and confirm that they only affect resources for this guide:
adc diff -f adc.yaml \
--include-resource-type consumer \
--include-resource-type service \
--label-selector docs-example=multi-auth
Synchronize the configuration to the gateway:
adc sync -f adc.yaml \
--include-resource-type consumer \
--include-resource-type service \
--label-selector docs-example=multi-auth
- Gateway API
- APISIX CRD
apiVersion: apisix.apache.org/v1alpha1
kind: Consumer
metadata:
namespace: aic
name: consumer1
spec:
gatewayRef:
name: apisix
credentials:
- type: basic-auth
name: cred-consumer1-basic-auth
config:
username: consumer1
password: consumer1_pwd
---
apiVersion: apisix.apache.org/v1alpha1
kind: Consumer
metadata:
namespace: aic
name: consumer2
spec:
gatewayRef:
name: apisix
credentials:
- type: key-auth
name: cred-consumer2-key-auth
config:
key: consumer2_pwd
---
apiVersion: v1
kind: Service
metadata:
namespace: aic
name: httpbin-external-domain
spec:
type: ExternalName
externalName: httpbin.org
---
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
namespace: aic
name: multi-auth-plugin-config
spec:
plugins:
- name: multi-auth
config:
auth_plugins:
- basic-auth: {}
- key-auth:
hide_credentials: true
header: apikey
query: apikey
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: aic
name: multi-auth-route
spec:
parentRefs:
- name: apisix
rules:
- matches:
- path:
type: Exact
value: /anything
filters:
- type: ExtensionRef
extensionRef:
group: apisix.apache.org
kind: PluginConfig
name: multi-auth-plugin-config
backendRefs:
- name: httpbin-external-domain
port: 80
Apply the configuration to your cluster:
kubectl apply -f multi-auth-ic.yaml
apiVersion: apisix.apache.org/v2
kind: ApisixConsumer
metadata:
namespace: aic
name: consumer1
spec:
ingressClassName: apisix
authParameter:
basicAuth:
value:
username: consumer1
password: consumer1_pwd
---
apiVersion: apisix.apache.org/v2
kind: ApisixConsumer
metadata:
namespace: aic
name: consumer2
spec:
ingressClassName: apisix
authParameter:
keyAuth:
value:
key: consumer2_pwd
---
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
namespace: aic
name: httpbin-external-domain
spec:
ingressClassName: apisix
externalNodes:
- type: Domain
name: httpbin.org
---
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
namespace: aic
name: multi-auth-route
spec:
ingressClassName: apisix
http:
- name: multi-auth-route
match:
paths:
- /anything
upstreams:
- name: httpbin-external-domain
plugins:
- name: multi-auth
enable: true
config:
auth_plugins:
- basic-auth: {}
- key-auth:
hide_credentials: true
header: apikey
query: apikey
Apply the configuration to your cluster:
kubectl apply -f multi-auth-ic.yaml
Send a request to the route with consumer1 basic authentication credentials:
curl -i "http://127.0.0.1:9080/anything" -u consumer1:consumer1_pwd
You should receive an HTTP/1.1 200 OK response.
Send another request to the route with consumer2 key authentication credential:
curl -i "http://127.0.0.1:9080/anything" -H 'apikey: consumer2_pwd'
You should again receive an HTTP/1.1 200 OK response.
Send a request to the route without any credential:
curl -i "http://127.0.0.1:9080/anything"
You should receive an HTTP/1.1 401 Unauthorized response.
With the gateway error log level set to warn or a more verbose level, check the error log after this failed request. It should contain one warning for each authentication method. Each warning identifies the authentication plugin, its status code, and its error message, which helps distinguish an invalid key from another authentication failure.
These results show that valid credentials for either configured method grant access, while a request that fails every method returns HTTP 401 and produces per-method diagnostics.