🤔 Introducing APISIX AI Gateway – Built for LLMs and AI workloads. Learn More

consumer-restriction

描述

consumer-restriction 插件基于消费者名称、路由 ID、服务 ID 或消费者组 ID 实现访问控制。

该插件需要与认证插件配合使用,例如 key-authjwt-auth,这意味着在使用场景中至少需要创建一个消费者。详情请参见下方示例。

属性

名称类型必选项默认值有效值描述
typestringconsumer_nameconsumer_name, service_id, route_id, consumer_group_id限制的依据。决定对白名单或黑名单检查哪个值。
whitelistarray[string]允许访问的值列表。whitelistblacklistallowed_by_methods 中至少需要配置一个。
blacklistarray[string]拒绝访问的值列表。whitelistblacklistallowed_by_methods 中至少需要配置一个。
allowed_by_methodsarray[object]指定每个消费者允许的 HTTP 方法的对象列表。whitelistblacklistallowed_by_methods 中至少需要配置一个。
allowed_by_methods[].userstring消费者名称。
allowed_by_methods[].methodsarray[string]GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS, CONNECT, TRACE, PURGE该消费者允许的 HTTP 方法列表。
rejected_codeinteger403>= 200请求被拒绝时返回的 HTTP 状态码。
rejected_msgstring请求被拒绝时返回给客户端的消息。

示例

以下示例演示了如何针对不同场景配置 consumer-restriction 插件。

示例中使用 key-auth 作为认证方式,你可以根据需要灵活调整为其他认证插件。

NOTE

你可以使用以下命令从 config.yaml 中获取 admin_key 并保存到环境变量中:

admin_key=$(yq '.deployment.admin.admin_key[0].key' /usr/local/apisix/conf/config.yaml | sed 's/"//g')

通过消费者名称限制访问

以下示例演示如何在路由上使用 consumer-restriction 插件,按消费者名称限制消费者访问,消费者通过 key-auth 进行认证。

admin-api

创建消费者 JohnDoe

curl "http://127.0.0.1:9180/apisix/admin/consumers" -X PUT \
  -H "X-API-KEY: ${admin_key}" \
  -d '{
    "username": "JohnDoe"
  }'

为该消费者创建 key-auth 凭证:

curl "http://127.0.0.1:9180/apisix/admin/consumers/JohnDoe/credentials" -X PUT \
  -H "X-API-KEY: ${admin_key}" \
  -d '{
    "id": "cred-john-key-auth",
    "plugins": {
      "key-auth": {
        "key": "john-key"
      }
    }
  }'

创建第二个消费者 JaneDoe

curl "http://127.0.0.1:9180/apisix/admin/consumers" -X PUT \
  -H "X-API-KEY: ${admin_key}" \
  -d '{
    "username": "JaneDoe"
  }'

为该消费者创建 key-auth 凭证:

curl "http://127.0.0.1:9180/apisix/admin/consumers/JaneDoe/credentials" -X PUT \
  -H "X-API-KEY: ${admin_key}" \
  -d '{
    "id": "cred-jane-key-auth",
    "plugins": {
      "key-auth": {
        "key": "jane-key"
      }
    }
  }'

创建启用 key 认证的路由,并配置 consumer-restriction 仅允许消费者 JaneDoe 访问:

curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
  -H "X-API-KEY: ${admin_key}" \
  -d '{
    "id": "consumer-restricted-route",
    "uri": "/get",
    "plugins": {
      "key-auth": {},
      "consumer-restriction": {
        "whitelist": ["JaneDoe"]
      }
    },
    "upstream" : {
      "nodes": {
        "httpbin.org":1
      }
    }
  }'

adc

adc.yaml
consumers:
  - username: JohnDoe
    credentials:
      - name: cred-john-key-auth
        type: key-auth
        config:
          key: john-key
  - username: JaneDoe
    credentials:
      - name: cred-jane-key-auth
        type: key-auth
        config:
          key: jane-key
services:
  - name: consumer-restriction-service
    routes:
      - name: consumer-restricted-route
        uris:
          - /get
        plugins:
          key-auth: {}
          consumer-restriction:
            whitelist:
              - "JaneDoe"
    upstream:
      type: roundrobin
      nodes:
        - host: httpbin.org
          port: 80
          weight: 1

将配置同步到网关:

adc sync -f adc.yaml

aic

通过 Ingress Controller 配置消费者时,消费者名称格式为 namespace_consumername。例如,aic 命名空间中名为 janedoe 的消费者,其名称变为 aic_janedoe。在 consumer-restrictionwhitelistblacklist 中请使用此格式。

gateway-api

consumer-restriction-ic.yaml
apiVersion: apisix.apache.org/v1alpha1
kind: Consumer
metadata:
  namespace: aic
  name: johndoe
spec:
  gatewayRef:
    name: apisix
  credentials:
    - type: key-auth
      name: john-key-auth
      config:
        key: john-key
---
apiVersion: apisix.apache.org/v1alpha1
kind: Consumer
metadata:
  namespace: aic
  name: janedoe
spec:
  gatewayRef:
    name: apisix
  credentials:
    - type: key-auth
      name: jane-key-auth
      config:
        key: jane-key
---
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: consumer-restriction-plugin-config
spec:
  plugins:
    - name: key-auth
      config:
        _meta:
          disable: false
    - name: consumer-restriction
      config:
        whitelist:
          - "aic_janedoe"
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  namespace: aic
  name: consumer-restriction-route
spec:
  parentRefs:
    - name: apisix
  rules:
    - matches:
        - path:
            type: Exact
            value: /get
      filters:
        - type: ExtensionRef
          extensionRef:
            group: apisix.apache.org
            kind: PluginConfig
            name: consumer-restriction-plugin-config
      backendRefs:
        - name: httpbin-external-domain
          port: 80

apisix-ingress-controller

consumer-restriction-ic.yaml
apiVersion: apisix.apache.org/v2
kind: ApisixConsumer
metadata:
  namespace: aic
  name: johndoe
spec:
  ingressClassName: apisix
  authParameter:
    keyAuth:
      value:
        key: john-key
---
apiVersion: apisix.apache.org/v2
kind: ApisixConsumer
metadata:
  namespace: aic
  name: janedoe
spec:
  ingressClassName: apisix
  authParameter:
    keyAuth:
      value:
        key: jane-key
---
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: consumer-restriction-route
spec:
  ingressClassName: apisix
  http:
    - name: consumer-restriction-route
      match:
        paths:
          - /get
      upstreams:
      - name: httpbin-external-domain
      plugins:
      - name: key-auth
        enable: true
      - name: consumer-restriction
        enable: true
        config:
          whitelist:
            - "aic_janedoe"

将配置应用到集群:

kubectl apply -f consumer-restriction-ic.yaml

以消费者 JohnDoe 的身份向路由发送请求:

curl -i "http://127.0.0.1:9080/get" -H 'apikey: john-key'

你应收到 HTTP/1.1 403 Forbidden 响应,包含以下消息:

{"message":"The consumer_name is forbidden."}

再以消费者 JaneDoe 的身份发送请求:

curl -i "http://127.0.0.1:9080/get" -H 'apikey: jane-key'

你应收到 HTTP/1.1 200 OK 响应,表示该消费者访问被允许。

通过消费者名称和 HTTP 方法限制访问

以下示例演示如何在路由上使用 consumer-restriction 插件,按消费者名称和 HTTP 方法限制消费者访问,消费者通过 key-auth 进行认证。

admin-api

创建消费者 JohnDoe

curl "http://127.0.0.1:9180/apisix/admin/consumers" -X PUT \
  -H "X-API-KEY: ${admin_key}" \
  -d '{
    "username": "JohnDoe"
  }'

为该消费者创建 key-auth 凭证:

curl "http://127.0.0.1:9180/apisix/admin/consumers/JohnDoe/credentials" -X PUT \
  -H "X-API-KEY: ${admin_key}" \
  -d '{
    "id": "cred-john-key-auth",
    "plugins": {
      "key-auth": {
        "key": "john-key"
      }
    }
  }'

创建第二个消费者 JaneDoe

curl "http://127.0.0.1:9180/apisix/admin/consumers" -X PUT \
  -H "X-API-KEY: ${admin_key}" \
  -d '{
    "username": "JaneDoe"
  }'

为该消费者创建 key-auth 凭证:

curl "http://127.0.0.1:9180/apisix/admin/consumers/JaneDoe/credentials" -X PUT \
  -H "X-API-KEY: ${admin_key}" \
  -d '{
    "id": "cred-jane-key-auth",
    "plugins": {
      "key-auth": {
        "key": "jane-key"
      }
    }
  }'

创建启用 key 认证的路由,并使用 consumer-restriction 仅允许消费者使用所配置的 HTTP 方法:

curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
  -H "X-API-KEY: ${admin_key}" \
  -d '{
    "id": "consumer-restricted-route",
    "uri": "/anything",
    "plugins": {
      "key-auth": {},
      "consumer-restriction": {
        "allowed_by_methods":[
          {
            "user": "JohnDoe",
            "methods": ["GET"]
          },
          {
            "user": "JaneDoe",
            "methods": ["POST"]
          }
        ]
      }
    },
    "upstream" : {
      "nodes": {
        "httpbin.org":1
      }
    }
  }'

adc

adc.yaml
consumers:
  - username: JohnDoe
    credentials:
      - name: cred-john-key-auth
        type: key-auth
        config:
          key: john-key
  - username: JaneDoe
    credentials:
      - name: cred-jane-key-auth
        type: key-auth
        config:
          key: jane-key
services:
  - name: consumer-restriction-service
    routes:
      - name: consumer-restricted-route
        uris:
          - /anything
        plugins:
          key-auth: {}
          consumer-restriction:
            allowed_by_methods:
              - user: "JohnDoe"
                methods:
                  - "GET"
              - user: "JaneDoe"
                methods:
                  - "POST"
    upstream:
      type: roundrobin
      nodes:
        - host: httpbin.org
          port: 80
          weight: 1

将配置同步到网关:

adc sync -f adc.yaml

aic

gateway-api

consumer-restriction-ic.yaml
apiVersion: apisix.apache.org/v1alpha1
kind: Consumer
metadata:
  namespace: aic
  name: johndoe
spec:
  gatewayRef:
    name: apisix
  credentials:
    - type: key-auth
      name: john-key-auth
      config:
        key: john-key
---
apiVersion: apisix.apache.org/v1alpha1
kind: Consumer
metadata:
  namespace: aic
  name: janedoe
spec:
  gatewayRef:
    name: apisix
  credentials:
    - type: key-auth
      name: jane-key-auth
      config:
        key: jane-key
---
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: consumer-restriction-methods-config
spec:
  plugins:
    - name: key-auth
      config:
        _meta:
          disable: false
    - name: consumer-restriction
      config:
        allowed_by_methods:
          - user: "aic_johndoe"
            methods:
              - "GET"
          - user: "aic_janedoe"
            methods:
              - "POST"
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  namespace: aic
  name: consumer-restriction-route
spec:
  parentRefs:
    - name: apisix
  rules:
    - matches:
        - path:
            type: Exact
            value: /anything
      filters:
        - type: ExtensionRef
          extensionRef:
            group: apisix.apache.org
            kind: PluginConfig
            name: consumer-restriction-methods-config
      backendRefs:
        - name: httpbin-external-domain
          port: 80

将配置应用到集群:

kubectl apply -f consumer-restriction-ic.yaml

apisix-ingress-controller

consumer-restriction-ic.yaml
apiVersion: apisix.apache.org/v2
kind: ApisixConsumer
metadata:
  namespace: aic
  name: johndoe
spec:
  ingressClassName: apisix
  authParameter:
    keyAuth:
      value:
        key: john-key
---
apiVersion: apisix.apache.org/v2
kind: ApisixConsumer
metadata:
  namespace: aic
  name: janedoe
spec:
  ingressClassName: apisix
  authParameter:
    keyAuth:
      value:
        key: jane-key
---
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: consumer-restriction-route
spec:
  ingressClassName: apisix
  http:
    - name: consumer-restriction-route
      match:
        paths:
          - /anything
      upstreams:
      - name: httpbin-external-domain
      plugins:
      - name: key-auth
        enable: true
      - name: consumer-restriction
        enable: true
        config:
          allowed_by_methods:
            - user: "aic_johndoe"
              methods:
                - "GET"
            - user: "aic_janedoe"
              methods:
                - "POST"

将配置应用到集群:

kubectl apply -f consumer-restriction-ic.yaml

以消费者 JohnDoe 的身份发送 POST 请求到路由:

curl -i "http://127.0.0.1:9080/anything" -X POST -H 'apikey: john-key'

你应收到 HTTP/1.1 403 Forbidden 响应,包含以下消息:

{"message":"The consumer_name is forbidden."}

再以消费者 JohnDoe 的身份发送 GET 请求:

curl -i "http://127.0.0.1:9080/anything" -X GET -H 'apikey: john-key'

你应收到 HTTP/1.1 200 OK 响应,表示该消费者访问被允许。

你还可以以消费者 JaneDoe 的身份发送请求,验证配置是否与路由上 consumer-restriction 插件中的设置一致。

通过服务 ID 限制访问

以下示例演示如何使用 consumer-restriction 插件按服务 ID 限制消费者访问,消费者通过 key-auth 进行认证。

admin-api

创建两个示例服务:

curl "http://127.0.0.1:9180/apisix/admin/services" -X PUT \
  -H "X-API-KEY: ${admin_key}" \
  -d '{
    "id": "srv-1",
    "plugins": {
      "key-auth": {}
    },
    "upstream": {
      "type": "roundrobin",
      "nodes": {
        "httpbin.org":1
      }
    }
  }'
curl "http://127.0.0.1:9180/apisix/admin/services" -X PUT \
  -H "X-API-KEY: ${admin_key}" \
  -d '{
    "id": "srv-2",
    "plugins": {
      "key-auth": {}
    },
    "upstream": {
      "type": "roundrobin",
      "nodes": {
        "mock.api7.ai":1
      }
    }
  }'

创建一个消费者,并配置 consumer-restriction 仅允许访问 srv-1 服务:

curl "http://127.0.0.1:9180/apisix/admin/consumers" -X PUT \
  -H "X-API-KEY: ${admin_key}" \
  -d '{
    "username": "JohnDoe",
    "plugins": {
      "consumer-restriction": {
        "type": "service_id",
        "whitelist": ["srv-1"]
      }
    }
  }'

为该消费者创建 key-auth 凭证:

curl "http://127.0.0.1:9180/apisix/admin/consumers/JohnDoe/credentials" -X PUT \
  -H "X-API-KEY: ${admin_key}" \
  -d '{
    "id": "cred-john-key-auth",
    "plugins": {
      "key-auth": {
        "key": "john-key"
      }
    }
  }'

分别创建两条路由,各绑定到上面创建的一个服务:

curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
  -H "X-API-KEY: ${admin_key}" \
  -d '{
    "id": "srv-1-route",
    "uri": "/anything",
    "service_id": "srv-1"
  }'
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
  -H "X-API-KEY: ${admin_key}" \
  -d '{
    "id": "srv-2-route",
    "uri": "/srv-2",
    "service_id": "srv-2"
  }'

adc

adc.yaml
consumers:
  - username: JohnDoe
    credentials:
      - name: cred-john-key-auth
        plugins:
          key-auth:
            key: john-key
    plugins:
      consumer-restriction:
        type: service_id
        whitelist:
          - "srv-1"
services:
  - name: srv-1
    plugins:
      key-auth: {}
    routes:
      - name: srv-1-route
        uris:
          - /anything
    upstream:
      type: roundrobin
      nodes:
        - host: httpbin.org
          port: 80
          weight: 1
  - name: srv-2
    plugins:
      key-auth: {}
    routes:
      - name: srv-2-route
        uris:
          - /srv-2
    upstream:
      type: roundrobin
      nodes:
        - host: mock.api7.ai
          port: 80
          weight: 1

将配置同步到网关:

adc sync -f adc.yaml

aic

通过 Ingress Controller 配置路由时,APISIX 服务 ID 会自动生成为 {namespace}_{routeName}_{ruleIndex} 的哈希值,无法预先确定。建议改用基于消费者名称的限制方式。

srv-1 服务中的路由发送请求:

curl -i "http://127.0.0.1:9080/anything" -H 'apikey: john-key'

你应收到 HTTP/1.1 200 OK 响应,表示该消费者访问被允许。

srv-2 服务中的路由发送请求:

curl -i "http://127.0.0.1:9080/srv-2" -H 'apikey: john-key'

你应收到 HTTP/1.1 403 Forbidden 响应,包含以下消息:

{"message":"The service_id is forbidden."}