ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Apache APISIX key-auth 插件完全指南:基于 Consumer 的 API 密钥身份验证实战

Apache APISIX key-auth 插件完全指南:基于 Consumer 的 API 密钥身份验证实战 Apache APISIX key-auth 插件完全指南基于 Consumer 的 API 密钥身份验证实战【免费下载链接】apisixThe Cloud-Native API Gateway项目地址: https://gitcode.com/GitHub_Trending/ap/apisixkey-auth是 Apache APISIX 中最基础、使用最广泛的认证类插件它通过在请求的 Header 或 Query String 中携带 API Key 来验证调用方身份。本文以官方文档 key-auth 插件说明 为主线结合 插件源码、单元测试 与 Consumer 机制 的实现细节完整讲解插件的属性配置、Consumer 与 Route 的配合方式、测试验证、Secret 集成与加密存储帮助你在实际网关场景中正确、安全地落地 API 密钥认证。插件概述与工作原理key-auth插件用于向 Route 或 Service 添加身份验证密钥API Key它本身并不存储密钥而是依赖 APISIX 的Consumer消费者机制先在 Consumer 上声明唯一的key再在 Route 或 Service 上挂载key-auth插件请求到达网关后插件从请求的 Header 或 Query String 中取出 key与 Consumer 注册的 key 进行比对从而完成身份验证。从源码结构看key-auth通过type auth声明自己属于认证类插件并设置了priority 2500的高优先级确保它在请求生命周期中尽早执行apisix/plugins/key-auth.lualocal _M { version 0.1, priority 2500, type auth, name plugin_name, schema schema, consumer_schema consumer_schema, }它只实现了一个核心钩子rewriteapisix/plugins/key-auth.lua在rewrite阶段完成 key 的提取、校验与 Consumer 绑定工作流程如下提取 key优先从conf.header指定的 Header 中读取读取不到时再从conf.query指定的 Query String 参数中读取。缺失拦截两处都取不到 key直接返回401响应体为{message:Missing API key in request}。匹配 Consumer通过consumer_mod.plugin(plugin_name)获取注册了key-auth的所有 Consumer 配置再以key为键建立哈希映射consumers_kv用请求中的 key 精确匹配。校验失败拦截匹配不到 Consumer 时返回401响应体为{message:Invalid API key in request}。隐藏凭据可选若hide_credentials为true根据 key 的来源Header 或 Query String将其从请求中移除避免认证信息透传给上游。绑定 Consumer调用consumer_mod.attach_consumer(ctx, consumer, consumer_conf)将匹配到的 Consumer 信息挂载到请求上下文供后续插件如consumer-restriction、限流限频插件消费。属性详解key-auth的属性分为Consumer 端与RouterRoute/Service端两组前者定义密钥本身后者定义密钥的获取方式与传递行为。Consumer 端属性名称类型必选项描述keystring是不同的 Consumer 应有不同的key它应当是唯一的。如果多个 Consumer 使用了相同的key将会出现请求匹配异常。该字段支持使用 APISIX Secret 资源将值保存在 Secret Manager 中。Consumer 端的 schema 同时声明了encrypt_fields {key}apisix/plugins/key-auth.lua意味着该字段在开启数据加密后会被加密存储在 etcd 中具体机制见下文「加密存储」小节。关于key的唯一性源码中建立了consumers[key]的哈希索引apisix/plugins/key-auth.lua后写入的同名 key 会覆盖先前的映射这正是文档强调「多个 Consumer 使用相同 key 会出现请求匹配异常」的原因。因此生产环境中务必保证每个 Consumer 的key全局唯一。Router 端属性名称类型必选项默认值描述headerstring否apikey设置我们从哪个 header 获取 key。querystring否apikey设置我们从哪个 query string 获取 key优先级低于header。hide_credentialsbool否false当设置为false时将含有认证信息的 header 或 query string 传递给 Upstream。如果为true时将删除对应的 header 或 query string具体删除哪一个取决于是从 header 获取 key 还是从 query string 获取 key。以上默认值在 schema 定义 中均有体现header与query默认为apikeyhide_credentials默认为false。需要注意的是header 优先于 query只有当 header 中取不到 key 时插件才会尝试从 query string 获取apisix/plugins/key-auth.lua。若两个来源同时携带 key实际生效的是 header 中的值hide_credentials也只会删除实际被使用的那一个来源测试用例 TEST 19 与 TEST 23 专门验证了这一行为t/plugin/key-auth.t。启用插件创建 Consumer 与配置 Route启用key-auth需要两步先创建携带唯一 key 的 Consumer再在 Route 上挂载插件。以下命令均通过 Admin API 完成使用前请先从 conf/config.yaml 中取出admin_key并写入环境变量admin_key$(yq .deployment.admin.admin_key[0].key conf/config.yaml | sed s///g)注意config.yaml中admin_key默认可能为空字符串此时 APISIX 会自动生成随机 token 并回写配置文件生产环境强烈建议使用外部机制生成并保管该 token见 conf/config.yaml 的注释说明。第一步创建 Consumercurl http://127.0.0.1:9180/apisix/admin/consumers \ -H X-API-KEY: $admin_key -X PUT -d { username: jack, plugins: { key-auth: { key: auth-one } } }该请求向 Admin API 注册了一个用户名为jack的 Consumer其key-auth插件的密钥为auth-one。此操作也可通过 APISIX Dashboard 的 Web 界面完成在 Consumer 页面创建消费者并添加key-auth插件即可。第二步创建 Route 并挂载插件curl http://127.0.0.1:9180/apisix/admin/routes/1 \ -H X-API-KEY: $admin_key -X PUT -d { methods: [GET], uri: /index.html, id: 1, plugins: { key-auth: {} }, upstream: { type: roundrobin, nodes: { 127.0.0.1:1980: 1 } } }Route 上使用空的key-auth: {}即表示启用插件并全部使用默认配置header 与 query 均为apikey。此时访问/index.html的 GET 请求必须携带有效的apikey才能通过网关。自定义 Header 名称如果你不想从默认的apikeyheader 获取 key可以在插件配置中自定义 header例如使用更常见的Authorization{ key-auth: { header: Authorization } }测试用例 TEST 10 / TEST 11 验证了自定义 header 后请求Authorization: auth-one能正常通过t/plugin/key-auth.t。同理也可以通过query: auth自定义 query 参数名随后以GET /hello?authauth-one访问TEST 12 / TEST 13。测试插件验证三种典型场景插件配置完成后可通过以下命令验证认证行为。场景一携带正确的 key放行curl http://127.0.0.2:9080/index.html -H apikey: auth-one -iHTTP/1.1 200 OK ...场景二未携带 key返回 401curl http://127.0.0.2:9080/index.html -iHTTP/1.1 401 Unauthorized ... {message:Missing API key in request}场景三key 错误返回 401curl http://127.0.0.2:9080/index.html -H apikey: abcabcabc -iHTTP/1.1 401 Unauthorized ... {message:Invalid API key in request}这三种场景与单元测试中 TEST 5valid consumer、TEST 6invalid consumer、TEST 7not found apikey header一一对应t/plugin/key-auth.t错误响应的 message 文本也与源码中的返回值完全一致可直接作为排障时的对照依据。关于 401 的补充说明在 HTTP 规范中401 Unauthorized通常要求配合WWW-Authenticate响应头使用。key-auth插件直接返回401而没有附加该头因此在实践中若客户端如部分浏览器或 SDK依赖WWW-Authenticate触发认证流程需结合response-rewrite插件或业务侧逻辑自行补充。这一行为并未在当前仓库的插件实现中体现使用前应结合自身客户端兼容性进行评估。hide_credentials控制认证信息是否透传上游hide_credentials用于决定认证信息Header 或 Query String 中的 key是否继续传递给 Upstreamfalse默认含有认证信息的 header 或 query string 原样传递给 Upstream。测试用例 TEST 15 验证了hide_credentialsfalse时上游能收到apikey: auth-one请求头t/plugin/key-auth.t。true删除对应的 header 或 query string。删除的目标取决于 key 实际来自何处——从 header 取到就删 header从 query 取到就删 query且只删除被使用的那一个来源不会误删其他同名无关参数。底层实现在 apisix/plugins/key-auth.lua通过core.request.set_header(ctx, conf.header, nil)删除 header或通过core.request.set_uri_args移除 query 参数。相关测试覆盖了各种组合t/plugin/key-auth.t测试用例场景预期行为TEST 17header 携带 keyhide_credentialstrue上游请求头中无apikeyTEST 18header 携带 key 与无关头test仅删除apikey保留testTEST 19header 与 query 同时携带 key删除 headerquery 参数保留TEST 21query 携带 keyhide_credentialstrue上游 query 参数中无authTEST 23header 与 query 同时携带 key自定义auth删除 queryheader 保留生产实践建议如果上游业务不需要感知调用方身份应将hide_credentials设为true避免 API Key 泄露给后端服务或第三方日志系统。集成 APISIX Secret将密钥托管给外部密钥管理服务Consumer 端的key字段支持 APISIX Secret 引用可将明文密钥从配置中抽离存放到环境变量或 HashiCorp Vault 等密钥管理服务中。APISIX Secret 的目标是确保密钥在整个平台中不以明文形式存在docs/zh/latest/terminology/secret.md。从源码看key-auth的密钥解析发生在 Consumer 缓存构建阶段create_consume_cache会调用secret.fetch_secrets将auth_conf中的 Secret 引用解析为真实值后再以 key 建立索引apisix/consumer.lua这意味着 Secret 解析结果带有缓存密钥轮换后需要等待缓存过期默认 TTL 300 秒或触发配置版本更新才会生效。使用环境变量引用密钥curl http://127.0.0.1:9180/apisix/admin/consumers \ -H X-API-KEY: $admin_key -X PUT -d { username: jack, plugins: { key-auth: { key: $env://test_auth } } }对应测试用例 TEST 26 / TEST 27 使用env test_authauthone;声明环境变量后请求GET /hello?authauthone验证通过t/plugin/key-auth.t。引用格式为$ENV://$env_name/$sub_key支持系统环境变量与 Nginxenv指令配置的变量。使用 HashiCorp Vault 引用密钥先创建 Vault 资源配置再在 Consumer 中引用curl http://127.0.0.1:9180/apisix/admin/secrets/vault/test1 \ -H X-API-KEY: $admin_key -X PUT -d { uri: http://127.0.0.1:8200, prefix: kv/apisix, token: root }curl http://127.0.0.1:9180/apisix/admin/consumers \ -H X-API-KEY: $admin_key -X PUT -d { username: jack, plugins: { key-auth: { key: $secret://vault/test1/jack/key } } }测试用例 TEST 28 ~ TEST 32 完整演示了「创建 Vault 资源 → 写入kv/apisix/jack中的keyauthtwo→ 以$secret://vault/test1/jack/key引用 → 用authtwo请求验证通过」的全链路t/plugin/key-auth.t。Vault 的 token 本身也支持通过$ENV://VAULT_TOKEN引用避免明文写入配置。密钥加密存储encrypt_fields 与 data_encryptionkey-auth的 Consumer schema 声明了encrypt_fields {key}apisix/plugins/key-auth.lua表示该字段支持加密存储。开启后通过 Admin API 新增或更新资源时key会被自动加密后存入 etcd通过 Admin API 读取资源以及插件运行时APISIX 会自动解密使用。该能力需要 APISIX 版本不小于 3.1并在 conf/config.yaml 中开启data_encryption配置apisix: data_encryption: enable: true keyring: - edd1c9f0985e76a2 - qeddd145sfvddff4keyring是一个数组可配置多个密钥APISIX 会按顺序依次尝试用 keyring 中的密钥解密数据失败则尝试下一个直到成功docs/zh/latest/plugin-develop.md。enable_encrypt_fields默认开启测试文件通过yaml_config显式关闭以验证非加密路径生产环境建议保持开启并妥善保管keyring。加密存储对key-auth的价值在于即使 etcd 中的数据被窃取攻击者看到的也只是密文无法直接获取 API Key 明文。删除插件需要禁用key-auth时通过 Admin API 将 Route 配置中的plugins置空APISIX 会自动重新加载相关配置无需重启服务curl http://127.0.0.1:9180/apisix/admin/routes/1 \ -H X-API-KEY: $admin_key -X PUT -d { methods: [GET], uri: /index.html, id: 1, plugins: { }, upstream: { type: roundrobin, nodes: { 127.0.0.1:1980: 1 } } }删除后该 Route 上的请求将不再进行 key 校验直接转发至上游。需要注意的是删除 Route 上的插件并不会删除 Consumer 上的key-auth配置如需彻底移除还需另行更新或删除对应的 Consumer 资源。与其它认证插件的取舍key-auth属于 APISIX 认证插件家族type auth中的轻量级方案与basic-auth、jwt-auth、hmac-auth、keycloak、openid-connect等并列。它适用于对安全性要求适中、希望以最小成本快速接入的场景如内部服务间调用、简单移动端 API若需要防重放、请求签名、短期令牌或对接 OIDC 等企业身份体系则应评估hmac-auth、jwt-auth或openid-connect等方案。由于key-auth的 key 是长期有效的静态凭据且明文随请求传输除非配合 HTTPS请务必全程使用 HTTPS 传输避免 key 在链路上被截获为每个调用方分配独立且唯一的 key便于审计与单独吊销结合 consumer-restriction 插件 对已认证 Consumer 做进一步的访问控制定期轮换 key并结合上文介绍的 Secret 引用与加密存储减少明文暴露面。参考资源插件官方文档docs/zh/latest/plugins/key-auth.md插件源码实现apisix/plugins/key-auth.luaConsumer 机制与密钥解析apisix/consumer.lua单元测试32 个用例覆盖 schema、自定义 header/query、hide_credentials、Secret 引用等t/plugin/key-auth.tConsumer 概念docs/zh/latest/terminology/consumer.mdSecret 概念与使用docs/zh/latest/terminology/secret.md加密存储字段规范docs/zh/latest/plugin-develop.mdAdmin API 密钥配置conf/config.yaml【免费下载链接】apisixThe Cloud-Native API Gateway项目地址: https://gitcode.com/GitHub_Trending/ap/apisix创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表