Skip to main content

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/v2beta3kind: ApisixConsumermetadata:  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/v2beta3kind: ApisixConsumermetadata:  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/v2beta3kind: ApisixConsumermetadata:  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/v2beta3kind: ApisixConsumermetadata:  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.

#Now, try to deploy httpbin to your Kubernetes cluster:kubectl run httpbin --image kennethreitz/httpbin --port 80kubectl 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 - <<EOFapiVersion: apisix.apache.org/v2beta3kind: ApisixConsumermetadata:  name: foospec:  authParameter:    keyAuth:      value:        key: foo-keyEOF
  • Creates an ApisixRoute, and enable plugin key-auth:
kubectl apply -f - <<EOFapiVersion: apisix.apache.org/v2beta3kind: ApisixRoutemetadata:  name: httpserver-routespec:  http:  - name: rule1    match:      hosts:      - httpbin.org      paths:      - /*    backends:    - serviceName: httpbin      servicePort: 80    authentication:      enable: true      type: keyAuthEOF
  • 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 Secret object:
kubectl apply -f - <<EOFapiVersion: v1kind: Secretmetadata:  name: foovaluedata:  key: Zm9vLWtleQ==EOF
  • Creates an ApisixConsumer and reference Secret object:
kubectl apply -f - <<EOFapiVersion: apisix.apache.org/v2beta3kind: ApisixConsumermetadata:  name: foospec:  authParameter:    keyAuth:      secretRef:        name: foovalueEOF
  • Creates an ApisixRoute, and enables plugin key-auth:
kubectl apply -f - <<EOFapiVersion: apisix.apache.org/v2beta3kind: ApisixRoutemetadata:  name: httpserver-routespec:  http:  - name: rule1    match:      hosts:      - httpbin.org      paths:      - /*    backends:    - serviceName: httpbin      servicePort: 80    authentication:      enable: true      type: keyAuthEOF
  • 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 - <<EOFapiVersion: apisix.apache.org/v2beta3kind: ApisixConsumermetadata:  name: foo2spec:  authParameter:    jwtAuth:      value:        key: foo2-keyEOF
  • Use the public-api plugin to expose the public API:
kubectl apply -f - <<EOFapiVersion: apisix.apache.org/v2beta3kind: ApisixRoutemetadata:  name: defaultspec:  http:  - name: public-api    match:      paths:      - /apisix/plugin/jwt/sign    backends:    - serviceName: apisix-admin      servicePort: 9180    plugins:    - name: public-api      enable: trueEOF
  • Creates an ApisixRoute, and enable the jwt-auth plugin:
kubectl apply -f - <<EOFapiVersion: apisix.apache.org/v2beta3kind: ApisixRoutemetadata: name: httpbin-routespec: http: - name: rule1   match:     hosts:     - httpbin.org     paths:       - /*   backends:   - serviceName: httpbin     servicePort: 80   authentication:     enable: true     type: jwtAuthEOF
  • 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 username of consumer to a whitelist or blacklist (supporting single or multiple consumers) to restrict access to services or routes.

  • Create ApisixConsumer jack1:

kubectl apply -f - <<EOFapiVersion: apisix.apache.org/v2beta3kind: ApisixConsumermetadata:  name: jack1spec:  authParameter:    keyAuth:      value:        key: jack1-keyEOF
  • Create ApisixConsumer jack2:
kubectl apply -f - <<EOFapiVersion: apisix.apache.org/v2beta3kind: ApisixConsumermetadata:  name: jack2spec:  authParameter:    keyAuth:      value:        key: jack2-keyEOF
  • Creates an ApisixRoute, and enable config whitelist of the plugin consumer-restriction:
kubectl apply -f - <<EOFapiVersion: apisix.apache.org/v2beta3kind: ApisixRoutemetadata: name: httpserver-routespec: 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 defaultNAME    AGEfoo     14hjack1   14hjack2   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_methods of the plugin consumer-restriction:
kubectl apply -f - <<EOFapiVersion: apisix.apache.org/v2beta3kind: ApisixRoutemetadata: name: httpserver-routespec: 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 - <<EOFapiVersion: apisix.apache.org/v2beta3kind: ApisixRoutemetadata: name: httpserver-routespec: 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...