Enable authentication and restriction
Description#
Consumers are used for the authentication method controlled by Apache APISIX, if users want to use their own auth system or 3rd party systems, use OIDC.
Attributes#
Authentication#
Key Auth#
Consumers add their key either in a header or query string parameter to authenticate their requests. For more information about Key Auth, please refer to APISIX key-auth plugin.
Also, we can using the secretRef field to reference a K8s Secret object so that we can avoid the hardcoded sensitive data in the ApisixConsumer object. For reference Secret use example, please refer to the key-auth-reference-secret-object.
Key Auth yaml configure
apiVersion: apisix.apache.org/v2
kind: ApisixConsumer
metadata:
name: ${name}
spec:
authParameter:
keyAuth:
value:
key: ${key} #required
Basic Auth#
Consumers add their key in a header to authenticate their requests. For more information about Basic Auth, please refer to APISIX basic-auth plugin.
Also, we can using the secretRef field to reference a K8s Secret object so that we can avoid the hardcoded sensitive data in the ApisixConsumer object. For reference Secret use example, please refer to the key-auth-reference-secret-object.
Basic Auth yaml configure
apiVersion: apisix.apache.org/v2
kind: ApisixConsumer
metadata:
name: ${name}
spec:
authParameter:
basicAuth:
value:
username: ${username} #required
password: ${password} #required
JWT Auth#
The consumer then adds its key to the query string parameter, request header, or cookie to verify its request. For more information about JWT Auth, please refer to APISIX jwt-auth plugin.
Also, we can using the secretRef field to reference a K8s Secret object so that we can avoid the hardcoded sensitive data in the ApisixConsumer object. For reference Secret use example, please refer to the key-auth-reference-secret-object.
Need to expose API
This plugin will add /apisix/plugin/jwt/sign to sign. You may need to use public-api plugin to expose it.
JWT Auth yaml configure
apiVersion: apisix.apache.org/v2
kind: ApisixConsumer
metadata:
name: ${name}
spec:
authParameter:
wolfRbac:
value:
key: "${key}" #required
secret: "${secret}" #optional
public_key: "${public_key}" #optional, required when algorithm attribute selects RS256 algorithm.
private_key: "{private_key}" #optional, required when algorithm attribute selects RS256 algorithm.
algorithm: "${HS256 | HS512 | RS256}" #optional
exp: ${ 86400 | token's expire time, in seconds} #optional
algorithm: ${true | false} #optional
Wolf RBAC#
To use wolfRbac authentication, you need to start and install wolf-server. For more information about Wolf RBAC, please refer to APISIX wolf-rbac plugin.
Also, we can using the secretRef field to reference a K8s Secret object so that we can avoid the hardcoded sensitive data in the ApisixConsumer object. For reference Secret use example, please refer to the key-auth-reference-secret-object.
This plugin will add several APIs
- /apisix/plugin/wolf-rbac/login
- /apisix/plugin/wolf-rbac/change_pwd
- /apisix/plugin/wolf-rbac/user_info
You may need to use public-api plugin to expose it.
Wolf RBAC yaml configure
apiVersion: apisix.apache.org/v2
kind: ApisixConsumer
metadata:
name: ${name}
spec:
authParameter:
wolfRBAC:
value:
server: "${server of wolf-rbac}" #optional
appid: "${appid of wolf-rbac}" #optional
header_prefix: "${X- | X-UserId | X-Username | X-Nickname}" #optional
Restriction#
whitelist or blacklist#
whitelist: Grant full access to all users specified in the provided list, has the priority over allowed_by_methods
blacklist: Reject connection to all users specified in the provided list, has the priority over whitelist
whitelist or blacklist with consumer-restriction yaml configure
plugins:
- name: consumer-restriction
enable: true
config:
blacklist:
- "${consumer_name}"
- "${consumer_name}"
allowed_by_methods#
HTTP methods can be methods:["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS", "CONNECT", "TRACE", "PURGE"]
allowed_by_methods with consumer-restriction yaml configure
plugins:
- name: consumer-restriction
enable: true
config:
allowed_by_methods:
- user: "${consumer_name}"
methods:
- "${GET | POST | PUT |...}"
- "${GET | POST | PUT |...}"
- user: "${consumer_name}"
methods:
- "${GET | POST | PUT |...}"
Example#
Refer to the corresponding e2e test case.
Prepare env#
To use this tutorial, you must deploy Ingress APISIX and httpbin in Kubernetes cluster.
- Installing
Ingress APISIX. - Deploy
httpbinservice.
#Now, try to deploy httpbin to your Kubernetes cluster:
kubectl run httpbin --image kennethreitz/httpbin --port 80
kubectl expose pod httpbin --port 80
How to enable Authentication#
Enable keyAuth#
The following is an example. The keyAuth is enabled on the specified route to restrict user access.
- Creates an ApisixConsumer, and set the attributes of plugin
key-auth:
kubectl apply -f - <<EOF
apiVersion: apisix.apache.org/v2
kind: ApisixConsumer
metadata:
name: foo
spec:
authParameter:
keyAuth:
value:
key: foo-key
EOF
- Creates an ApisixRoute, and enable plugin
key-auth:
kubectl apply -f - <<EOF
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: httpserver-route
spec:
http:
- name: rule1
match:
hosts:
- httpbin.org
paths:
- /*
backends:
- serviceName: httpbin
servicePort: 80
authentication:
enable: true
type: keyAuth
EOF
- Requests from foo:
kubectl exec -it -n ${namespace of Apache APISIX} ${pod of Apache APISIX} -- curl http://127.0.0.1:9080/anything -H 'Host: httpbin.org' -H 'apikey:foo-key' -i
HTTP/1.1 200 OK
...
Key Auth reference Secret object#
ApisixRoute with keyAuth consumer using secret example
- Creates a
Secretobject:
kubectl apply -f - <<EOF
apiVersion: v1
kind: Secret
metadata:
name: foovalue
data:
key: Zm9vLWtleQ==
EOF
- Creates an ApisixConsumer and reference
Secretobject:
kubectl apply -f - <<EOF
apiVersion: apisix.apache.org/v2
kind: ApisixConsumer
metadata:
name: foo
spec:
authParameter:
keyAuth:
secretRef:
name: foovalue
EOF
- Creates an ApisixRoute, and enables plugin
key-auth:
kubectl apply -f - <<EOF
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: httpserver-route
spec:
http:
- name: rule1
match:
hosts:
- httpbin.org
paths:
- /*
backends:
- serviceName: httpbin
servicePort: 80
authentication:
enable: true
type: keyAuth
EOF
- Requests from foo:
kubectl exec -it -n ${namespace of Apache APISIX} ${pod of Apache APISIX} -- curl http://127.0.0.1:9080/anything -H 'Host: httpbin.org' -H 'apikey:foo-key' -i
HTTP/1.1 200 OK
...
Enable JWT Auth#
- Creates an ApisixConsumer, and set the attributes of plugin
jwt-auth:
kubectl apply -f - <<EOF
apiVersion: apisix.apache.org/v2
kind: ApisixConsumer
metadata:
name: foo2
spec:
authParameter:
jwtAuth:
value:
key: foo2-key
EOF
- Use the
public-apiplugin to expose the public API:
kubectl apply -f - <<EOF
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: default
spec:
http:
- name: public-api
match:
paths:
- /apisix/plugin/jwt/sign
backends:
- serviceName: apisix-admin
servicePort: 9180
plugins:
- name: public-api
enable: true
EOF
- Creates an ApisixRoute, and enable the jwt-auth plugin:
kubectl apply -f - <<EOF
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: httpbin-route
spec:
http:
- name: rule1
match:
hosts:
- httpbin.org
paths:
- /*
backends:
- serviceName: httpbin
servicePort: 80
authentication:
enable: true
type: jwtAuth
EOF
- Get the token:
kubectl exec -it -n ${namespace of Apache APISIX} ${pod of Apache APISIX} -- curl http://127.0.0.1:9080/apisix/plugin/jwt/sign?key=foo2-key -H 'Host: httpbin.org' -i
HTTP/1.1 200 OK
...
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJ1c2VyLWtleSIsImV4cCI6MTU2NDA1MDgxMX0.Us8zh_4VjJXF-TmR5f8cif8mBU7SuefPlpxhH0jbPVI
- Without token:
kubectl exec -it -n ${namespace of Apache APISIX} ${pod of Apache APISIX} -- curl http://127.0.0.1:9080/anything -H 'Host: httpbin.org' -i
HTTP/1.1 401
...
{"message":"Missing JWT token in request"}
- Request header with token:
kubectl exec -it -n ${namespace of Apache APISIX} ${pod of Apache APISIX} -- curl http://127.0.0.1:9080/anything -H 'Host: httpbin.org' -H 'Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJ1c2VyLWtleSIsImV4cCI6MTU2NDA1MDgxMX0.Us8zh_4VjJXF-TmR5f8cif8mBU7SuefPlpxhH0jbPVI' -i
HTTP/1.1 200 OK
...
How to enable Restriction#
We can also use the consumer-restriction Plugin to restrict our user from accessing the API.
How to restrict consumer_name#
The following is an example. The consumer-restriction plugin is enabled on the specified route to restrict consumer_name access.
consumer_name: Add the
usernameofconsumerto a whitelist or blacklist (supporting single or multiple consumers) to restrict access to services or routes.Create ApisixConsumer jack1:
kubectl apply -f - <<EOF
apiVersion: apisix.apache.org/v2
kind: ApisixConsumer
metadata:
name: jack1
spec:
authParameter:
keyAuth:
value:
key: jack1-key
EOF
- Create ApisixConsumer jack2:
kubectl apply -f - <<EOF
apiVersion: apisix.apache.org/v2
kind: ApisixConsumer
metadata:
name: jack2
spec:
authParameter:
keyAuth:
value:
key: jack2-key
EOF
- Creates an ApisixRoute, and enable config
whitelistof the pluginconsumer-restriction:
kubectl apply -f - <<EOF
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: httpserver-route
spec:
http:
- name: rule1
match:
hosts:
- httpbin.org
paths:
- /*
backends:
- serviceName: httpbin
servicePort: 80
authentication:
enable: true
type: keyAuth
plugins:
- name: consumer-restriction
enable: true
config:
whitelist:
- "default_jack1"
EOF
The default_jack1 generation rules:
view ApisixConsumer resource object from this namespace default
$ kubectl get apisixconsumers.apisix.apache.org -n default
NAME AGE
foo 14h
jack1 14h
jack2 14h
${consumer_name} = ${namespace}_${ApisixConsumer_name} --> default_foo
${consumer_name} = ${namespace}_${ApisixConsumer_name} --> default_jack1
${consumer_name} = ${namespace}_${ApisixConsumer_name} --> default_jack2
Example usage
- Requests from jack1:
kubectl exec -it -n ${namespace of Apache APISIX} ${pod of Apache APISIX} -- curl http://127.0.0.1:9080/anything -H 'Host: httpbin.org' -H 'apikey:jack1-key' -i
HTTP/1.1 200 OK
...
- Requests from jack2:
kubectl exec -it -n ${namespace of Apache APISIX} ${pod of Apache APISIX} -- curl http://127.0.0.1:9080/anything -H 'Host: httpbin.org' -H 'apikey:jack2-key' -i
HTTP/1.1 403 Forbidden
...
{"message":"The consumer_name is forbidden."}
How to restrict allowed_by_methods#
This example restrict the user jack2 to only GET on the resource.
- Creates an ApisixRoute, and enable config
allowed_by_methodsof the pluginconsumer-restriction:
kubectl apply -f - <<EOF
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: httpserver-route
spec:
http:
- name: rule1
match:
hosts:
- httpbin.org
paths:
- /*
backends:
- serviceName: httpbin
servicePort: 80
authentication:
enable: true
type: keyAuth
plugins:
- name: consumer-restriction
enable: true
config:
allowed_by_methods:
- user: "default_jack1"
methods:
- "POST"
- "GET"
- user: "default_jack2"
methods:
- "GET"
EOF
Example usage
- Requests from jack1:
kubectl exec -it -n ${namespace of Apache APISIX} ${pod of Apache APISIX} -- curl http://127.0.0.1:9080/anything -H 'Host: httpbin.org' -H 'apikey:jack1-key' -i
HTTP/1.1 200 OK
...
kubectl exec -it -n ${namespace of Apache APISIX} ${pod of Apache APISIX} -- curl http://127.0.0.1:9080/anything -H 'Host: httpbin.org' -H 'apikey:jack1-key' -d '' -i
HTTP/1.1 200 OK
...
- Requests from jack2:
kubectl exec -it -n ${namespace of Apache APISIX} ${pod of Apache APISIX} -- curl http://127.0.0.1:9080/anything -H 'Host: httpbin.org' -H 'apikey:jack2-key' -i
HTTP/1.1 200 OK
...
kubectl exec -it -n ${namespace of Apache APISIX} ${pod of Apache APISIX} -- curl http://127.0.0.1:9080/anything -H 'Host: httpbin.org' -H 'apikey:jack2-key' -d '' -i
HTTP/1.1 403 Forbidden
...
Disable authentication and restriction#
To disable the consumer-restriction Plugin, you can set the enable: false from the plugins configuration.
Also, disable the keyAuth, you can set the enable: false from the authentication configuration.
kubectl apply -f - <<EOF
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: httpserver-route
spec:
http:
- name: rule1
match:
hosts:
- httpbin.org
paths:
- /*
backends:
- serviceName: httpbin
servicePort: 80
authentication:
enable: false
type: keyAuth
plugins:
- name: consumer-restriction
enable: false
config:
allowed_by_methods:
- user: "default_jack1"
methods:
- "POST"
- "GET"
- user: "default_jack2"
methods:
- "GET"
EOF
kubectl exec -it -n ${namespace of Apache APISIX} ${pod of Apache APISIX} -- curl http://127.0.0.1:9080/anything -H 'Host: httpbin.org' -i
HTTP/1.1 200 OK
...