consumer-restriction
consumer-restriction 插件支持基于消费者名称、路由 ID、服务 ID 或消费者组 ID 的访问控制。
该插件需要与认证插件一起工作,例如 key-auth 和 jwt-auth,这 意味着你的用例中应始终至少创建一个消费者。有关详细信息,请参阅下面的示例。
示例
以下示例展示了如何在不同场景下配置 consumer-restriction 插件。
虽然示例使用 key-auth 作为身份认证方法,但你可以根据需要轻松调整为其他身份认证插件。
基于消费者限制访问
以下示例演示了如何在路由上使用 consumer-restriction 插件,通过消费者名称限制消费者访问,其中消费者通过 key-auth 进行身份认证。
- Admin API
- ADC
- Ingress Controller
创建一个消费者 JohnDoe:
curl "http://127.0.0.1:9180/apisix/admin/consumers" -X PUT \
-H "X-API-KEY: ${ADMIN_API_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_API_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_API_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_API_KEY}" \
-d '{
"id": "cred-jane-key-auth",
"plugins": {
"key-auth": {
"key": "jane-key"
}
}
}'
接下来,创建一个启用了密钥身份认证的路由,并配置 consumer-restriction 仅允许消费者 JaneDoe:
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "consumer-restricted-route",
"uri": "/get",
"plugins": {
"key-auth": {},
"consumer-restriction": {
"whitelist": ["JaneDoe"]
}
},
"upstream" : {
"nodes": {
"httpbin.org":1
}
}
}'
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
使用 API7 Ingress Controller 配置消费者时,消费者名称将以 namespace_consumername 格式生成。例如,aic 命名空间中名为 janedoe 的消费者会变为 aic_janedoe。请在 consumer-restriction 的 whitelist 或 blacklist 中使用此格式。
- Gateway API
- APISIX CRD
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
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
- ADC
- Ingress Controller
创建一个消费者 JohnDoe:
curl "http://127.0.0.1:9180/apisix/admin/consumers" -X PUT \
-H "X-API-KEY: ${ADMIN_API_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_API_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_API_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_API_KEY}" \
-d '{
"id": "cred-jane-key-auth",
"plugins": {
"key-auth": {
"key": "jane-key"
}
}
}'
接下来,创建一个启用了密钥身份认证的路由,并使用 consumer-restriction 仅允许消费者使用配置的 HTTP 方法:
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_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
}
}
}'
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
- Gateway API
- APISIX CRD
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
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
- ADC
- Ingress Controller
创建两个示例服务:
curl "http://127.0.0.1:9180/apisix/admin/services" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "srv-1",
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org":1
}
}
}'
curl "http://127.0.0.1:9180/apisix/admin/services" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "srv-2",
"upstream": {
"type": "roundrobin",
"nodes": {
"mock.api7.ai":1
}
}
}'
接下来,创建一个带有 key-auth 的消费者,并配置 consumer-restriction 仅允许 srv-1 服务:
curl "http://127.0.0.1:9180/apisix/admin/consumers" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"username": "JohnDoe",
"plugins": {
"key-auth": {
"key": "john-key"
},
"consumer-restriction": {
"type": "service_id",
"whitelist": ["srv-1"]
}
}
}'
最后,创建两个路由,每个路由属于之前创建的服务之一:
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_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_API_KEY}" \
-d '{
"id": "srv-2-route",
"uri": "/srv-2",
"service_id": "srv-2"
}'
consumers:
- username: JohnDoe
plugins:
key-auth:
key: john-key
consumer-restriction:
type: service_id
whitelist:
- "srv-1"
services:
- name: srv-1
routes:
- name: srv-1-route
uris:
- /anything
upstream:
type: roundrobin
nodes:
- host: httpbin.org
port: 80
weight: 1
- name: srv-2
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
使用 API7 Ingress Controller 配置路由时,APISIX 服务 ID 会自动生成为 {namespace}_{routeName}_{ruleIndex} 的哈希值。这些 ID 难以预先确定,建议改用基于消费者名称的限制方式。
向 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 401 Unauthorized 响应,并包含以下消息:
{"message":"The request is rejected, please check the service_id for this request"}