
Envoy API Key Auth HTTP 过滤器API Key 认证与客户端鉴权配置完全指南【免费下载链接】envoyCloud-native high-performance edge/middle/service proxy项目地址: https://gitcode.com/GitHub_Trending/en/envoy导读本文围绕 Envoy 的envoy.filters.http.api_key_authHTTP 过滤器系统讲解如何基于唯一 API Key 对客户端进行身份认证与简单的授权控制。该过滤器可从 HTTP 请求头、查询参数或 Cookie 中提取 API Key并与配置的凭据列表进行比对Key 有效且客户端被允许则放行Key 无效或缺失返回 401Key 有效但客户端未被允许则返回 403。读完本文你将掌握过滤器级配置、Per-Route 覆盖配置、客户端信息上游转发含隐藏凭据以及allowed/unauthorized/forbidden三类统计指标的完整实战用法并能结合源码理解其底层判定流程。过滤器概览与工作原理API Key Auth 过滤器是一个典型的 HTTP 解码阶段过滤器用于在请求进入路由处理之前完成身份认证与简单的客户端授权。其核心数据流如下提取 Key按照配置的key_sources顺序从请求头、查询参数或 Cookie 中提取 API Key校验凭据将提取到的 Key 与配置的credentials列表比对若不在列表中则视为无效客户端授权若存在 Per-Route 配置且指定了allowed_clients则进一步判断认证通过后的客户端是否被允许转发与隐藏可选地将客户端身份注入到上游转发请求头并可选地移除请求中的 API Key避免泄露给上游统计输出每次放行、拒绝分别累加allowed、unauthorized、forbidden计数器。该过滤器在源码中的核心实现位于 source/extensions/filters/http/api_key_auth/api_key_auth.cc其decodeHeaders方法api_key_auth.cc#L116-L187完整实现了上述判定链。过滤器的类型 URL 为type.googleapis.com/envoy.extensions.filters.http.api_key_auth.v3.ApiKeyAuth对应 proto 定义见 api/envoy/extensions/filters/http/api_key_auth/v3/api_key_auth.proto。过滤器级配置Filter Configuration配置字段说明ApiKeyAuth消息包含三个核心字段字段类型说明credentialsrepeated Credential用于认证客户端的凭据列表每个条目由唯一的key与关联的client组成属于敏感信息proto 中标记为sensitive若同一个 key 重复配置过滤器配置解析会直接报错 Duplicated credential keykey_sourcesrepeated KeySource从请求中提取 Key 的来源每个来源只能指定header、query、cookie三者之一若三者都为空配置解析会报错 One of header/query/cookie must be set.forwardingForwarding可选的转发配置控制向上游传播哪些客户端信息见下文上游转发一节其中KeySource的优先级与取值规则见 api_key_auth.proto#L93-L115header从指定请求头取值。如果该头有多个值取第一个如果头值以Bearer前缀开头该前缀会被自动剥离后再作为 Key。优先级最高query从指定查询参数取值多个值取第一个。当header未设置时生效优先级高于 cookiecookie从指定 Cookie 名取值。仅当header与query都未设置时生效。多个key_sources按配置顺序依次尝试取到第一个非空 Key 即停止。这一点在源码 api_key_auth.cc#L73-L81 中有直接体现对应的顺序回退行为由测试OrderOfKeySources验证见 test/extensions/filters/http/api_key_auth/api_key_auth_test.cc#L197。Credential条目要求key与client均非空proto 中均有min_len: 1校验且client是用于标识客户端或消费者的唯一身份 ID。完整配置示例以下示例将过滤器挂载到 HTTP Connection Manager 的过滤链上配置了两组凭据从Authorization请求头提取 Key并将客户端身份转发到上游完整配置见 docs/root/configuration/http/http_filters/_include/api-key-auth-filter.yamlhttp_filters: - name: api_key_auth typed_config: type: type.googleapis.com/envoy.extensions.filters.http.api_key_auth.v3.ApiKeyAuth credentials: - key: one_key client: one_client - key: another_key client: another_client key_sources: - header: Authorization forwarding: header: x-client-id hide_credentials: false - name: envoy.filters.http.router typed_config: type: type.googleapis.com/envoy.extensions.filters.http.router.v3.Router注意过滤器必须放置在envoy.filters.http.router之前因为路由过滤器负责将请求转发给上游集群。认证失败时的行为结合源码 api_key_auth.cc#L141-L168 与测试用例认证判定遵循以下规则未配置 key_sources直接拒绝返回 401响应体 Client authentication failed.响应明细response code details为missing_key_sources未配置 credentials直接拒绝返回 401响应明细为missing_credentials请求中找不到 Key返回 401响应明细为missing_api_key测试见NoHeaderApiKey、NoQueryApiKey、NoCookieApiKeyKey 不在凭据列表中返回 401响应明细为unknown_api_key测试见UnkonwnApiKeyKey 有效但客户端不在允许列表中返回 403响应明细为client_not_allowed测试见KnownApiKeyButNotAllowed。拒绝响应由onDenied方法api_key_auth.cc#L189-L199通过sendLocalReply直接本地返回并停止过滤器链迭代。上游转发与隐藏凭据ForwardingForwarding消息提供两个可选能力定义见 api_key_auth.proto#L117-L128字段类型默认值说明headerstring空客户端身份注入到上游请求时的头名为空则不注入hide_credentialsboolfalse为true时在转发前从请求中移除 API Key适用于所有已配置的 Key 来源header、query、cookie这两个选项可以单独启用也可以同时启用具体取决于期望的行为仅hide_credentials: true只剥离 Key不注入客户端信息仅设置header只注入客户端 IDKey 原样保留在上游请求中两者同时启用注入客户端 ID 的同时移除 Key。转发实现原理在源码 api_key_auth.cc#L170-L183 中认证成功后若forwarding.header非空则使用headers.setReferenceKey(header_name, client)将认证通过后关联的客户端 IDCredential.client写入指定请求头若hideCredentials()为true则调用key_sources-removeKey(headers)移除 API Key。removeKey的实现api_key_auth.cc#L83-L102会按来源分别处理header 直接删除请求头query 从 URL 中移除参数并重写路径cookie 则移除对应 Cookie。对应测试覆盖了 header/query/cookie 三种来源的转发与隐藏行为例如HeaderApiKeyWithForwardingapi_key_auth_test.cc#L489断言x-client-id被设置为user1且Authorization头在hide_credentials: false时仍然保留HideCredentialsHeaderWithForwardingapi_key_auth_test.cc#L591等用例则验证隐藏后的结果。Per-Route 配置与客户端鉴权覆盖机制API Key Auth 过滤器支持在路由route、虚拟主机virtual host或路由配置route configuration作用域内覆盖过滤器级配置覆盖可以是部分覆盖——只覆盖凭据列表、只覆盖 Key 来源、或两者同时覆盖。Per-Route 配置使用envoy.extensions.filters.http.api_key_auth.v3.ApiKeyAuthPerRoute类型字段说明credentials若非空则忽略过滤器级凭据使用本配置中的凭据key_sources若非空则忽略过滤器级 Key 来源使用本配置中的 Key 来源allowed_clients允许访问该路由/虚拟主机的客户端列表列表为空表示所有认证通过的客户端都被允许forwarding若非空则覆盖过滤器级转发配置在路由上禁用过滤器时使用通用的envoy.config.route.v3.FilterConfig并设置disabled: true例如示例中/static路由的处理方式。鉴权语义与注意事项allowed_clients提供的是极简的授权控制列表中的客户端必须是credentials中已定义客户端的子集认证成功后才做此判断。源码RouteConfig::allowClientapi_key_auth.h#L174-L176的逻辑是列表为空则全部放行否则仅放行列表内客户端。如果需要在认证之后做更复杂的授权如基于路径、方法、属性等官方建议改用 HTTP RBAC 过滤器其文档见 docs/root/configuration/http/http_filters/rbac_filter.rst。需要特别说明的一点proto 注释中已明确在同一个配置条目里同时设置allowed_clients和credentials并不会报错但通常没有意义因为二者功能高度重叠。唯一合理的组合场景是多个路由共享同一份凭据列表但各自使用不同的allowed_clients这正是下方示例中/admin路由的用法——它在 Per-Route 中只配置 Key 来源与允许客户端凭据仍继承过滤器级配置。组合示例路由级覆盖 客户端鉴权示例配置api-key-auth-filter.yaml#L16-L55对三条路由分别做了定制route_config: name: local_route virtual_hosts: - name: local_service domains: [*] routes: - match: path: /admin route: cluster: upstream_com typed_per_filter_config: api_key_auth: type: type.googleapis.com/envoy.extensions.filters.http.api_key_auth.v3.ApiKeyAuthPerRoute key_sources: - query: api_key allowed_clients: - another_client - match: path: /special route: cluster: upstream_com typed_per_filter_config: api_key_auth: type: type.googleapis.com/envoy.extensions.filters.http.api_key_auth.v3.ApiKeyAuthPerRoute credentials: - key: special_key client: special_client key_sources: - header: X-Special-Key - match: prefix: /static route: cluster: upstream_com typed_per_filter_config: api_key_auth: type: type.googleapis.com/envoy.config.route.v3.FilterConfig disabled: true - match: prefix: / route: cluster: upstream_com该示例中/admin路由将 Key 来源定制为查询参数api_key并且只允许another_client访问凭据仍使用过滤器级的one_key/another_key/special路由定制了自己的凭据列表special_key/special_client与 Key 来源请求头X-Special-Key且未配置allowed_clients因此所有认证通过的客户端均可访问/static路由通过disabled: true完全禁用过滤器其他路径/回退到过滤器级默认配置——从Authorization头提取 Key凭据为one_key/another_key并启用x-client-id转发。在解析上decodeHeaders通过resolveMostSpecificPerFilterConfig解析当前请求命中最具体的 Per-Route 配置并逐字段覆盖过滤器级配置api_key_auth.cc#L117-L139覆盖逻辑由RouteConfigOverrideCredentials、RouteConfigOverrideKeySource、RouteConfigOverrideKeySourceAndCredentials、RouteConfigOverrideForwarding等测试用例验证见 test/extensions/filters/http/api_key_auth/api_key_auth_test.cc#L280-L483。请求行为推演结合上述过滤器级配置与路由级配置官方文档给出了 6 个典型请求的预期行为# 允许API Key 有效且客户端被允许查询参数 api_keyanother_key另一个客户端 another_client GET /admin?api_keyanother_key HTTP/1.1 host: example.com # 拒绝 403API Key 有效one_key - one_client但客户端 one_client 不在 allowed_clients 中 GET /admin?api_keyone_key HTTP/1.1 host: example.com # 拒绝 401API Key 无效invalid_key 不在任何凭据列表中 GET /admin?api_keyinvalid_key HTTP/1.1 host: example.com # 允许/special 使用自定义凭据与 Key 来源X-Special-Key未配置客户端限制 GET /special HTTP/1.1 host: example.com X-Special-Key: special_key # 允许/static 路由过滤器被禁用 GET /static HTTP/1.1 host: example.com # 允许默认配置生效从 Authorization 头提取 Key剥离 Bearer 前缀后得到 one_key GET / HTTP/1.1 host: example.com Authorization: Bearer one_key统计指标Statistics过滤器在http.stat_prefix.api_key_auth.命名空间下输出三类计数器stat_prefix来自 HTTP Connection Manager 配置名称类型描述allowedCounter允许通过的请求总数unauthorizedCounter携带无效或缺失API Key 的请求总数forbiddenCounter携带有效 API Key 但客户端未被允许的请求总数统计宏定义于 source/extensions/filters/http/api_key_auth/api_key_auth.h#L21-L24allowed在请求继续转发时递增api_key_auth.cc#L185unauthorized与forbidden在onDenied中按响应码分支递增api_key_auth.cc#L191-L195。这三类指标可直接用于监控面板与告警例如观察unauthorized激增可判断是否存在恶意扫描或 Key 泄露。源码与测试参考如需深入阅读实现细节建议按以下路径展开proto 配置定义api/envoy/extensions/filters/http/api_key_auth/v3/api_key_auth.proto — 所有字段的完整语义与校验规则过滤器核心实现source/extensions/filters/http/api_key_auth/api_key_auth.h 与 source/extensions/filters/http/api_key_auth/api_key_auth.cc — Key 提取、凭据校验、转发与拒绝逻辑完整示例配置docs/root/configuration/http/http_filters/_include/api-key-auth-filter.yaml — 可直接参照运行的端到端示例含监听器、路由、集群、TLS 上游单元测试test/extensions/filters/http/api_key_auth/api_key_auth_test.cc — 覆盖所有来源提取、顺序回退、覆盖、转发、隐藏与鉴权场景模糊测试test/extensions/filters/http/api_key_auth/api_key_auth_fuzz_test.cc — 面向该过滤器的健壮性模糊测试入口。以上实现文件与测试文件共同构成了对本文所述全部行为的可验证依据读者可以据此在本地 Envoy 环境中复现并扩展验证。【免费下载链接】envoyCloud-native high-performance edge/middle/service proxy项目地址: https://gitcode.com/GitHub_Trending/en/envoy创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考