Apache APISIX forward-auth 插件实战将身份认证外包给外部服务的经典方案【免费下载链接】apisixThe Cloud-Native API Gateway项目地址: https://gitcode.com/GitHub_Trending/ap/apisix导读forward-auth是 Apache APISIX 提供的经典外部认证插件它将身份认证与授权逻辑从网关中剥离出来交给一个专门的认证服务处理APISIX 把客户端请求转发给该服务并阻塞原始请求认证通过后才放行到上游认证失败或认证服务不可用时则返回自定义错误或重定向响应。读完本文你将掌握forward-auth全部配置项的含义与适用场景、APISIX 自动生成的转发请求头规则并能基于 Admin API 快速搭建一套可复用的外部认证链路。核心原理外部认证模型的完整数据流forward-auth插件在 APISIX 中的角色是一个认证代理。其核心思想见 docs/zh/latest/plugins/forward-auth.md 描述部分是认证逻辑外置APISIX 不内置任何认证算法而是把客户端请求转发给专门的外部认证服务authorization service阻塞原始请求在认证服务返回结果之前原始请求不会继续流向上游结果替换当认证服务以非 2xx 状态响应时APISIX 直接用认证服务的响应状态码、响应头、响应体替换掉原本要返回给客户端的内容实现自定义错误或跳转认证页面的效果。从源码看该插件在 apisix/plugins/forward-auth.lua 中通过access阶段钩子实现插件优先级priority为2002在认证类插件中处于较高的执行顺序见 apisix/plugin.lua 中按优先级排序的逻辑。它使用resty.http库发起对认证服务的子请求整个流程发生在网关转发请求给上游之前因此任何到达该 Route 的请求都会先接受外部认证的体检。属性详解12 个配置项逐项拆解下表完整列出forward-auth插件的全部配置属性均与 apisix/plugins/forward-auth.lua 中的 schema 定义一一对应名称类型必选项默认值有效值描述uristring是认证服务的地址例如https://localhost:9188是唯一必填项。ssl_verifyboolean否true[true, false]当设置为true时验证 SSL 证书。若认证服务使用自签名证书需置为false。request_methodstring否GET[GET,POST]客户端向认证服务发送请求的方法。当设置为POST时会将客户端request body一并转发至认证服务。request_headersarray[string]否需要由客户端转发到认证服务的请求头白名单。如果没有设置则只发送 APISIX 提供的请求头例如X-Forwarded-XXX。upstream_headersarray[string]否认证通过时需要从认证服务响应中取出并转发到upstream的响应头。如果不设置则不转发任何请求头。client_headersarray[string]否认证失败时需要从认证服务响应中取出并发送给client的响应头。如果不设置则不转发任何响应头。timeoutinteger否3000ms[1, 60000]ms认证服务请求超时时间。keepaliveboolean否true[true, false]是否启用 HTTP 长连接复用与认证服务之间的 TCP 连接。keepalive_timeoutinteger否60000ms[1000, ...]ms长连接空闲超时时间。keepalive_poolinteger否5[1, ...]ms长连接池大小。allow_degradationboolean否false当设置为true时允许在认证服务器不可用时跳过身份验证直接放行请求。status_on_errorinteger否403[200,...,599]认证服务出现网络错误时返回给客户端的 HTTP 状态码。默认状态为403。几个容易被忽视的细节request_method与POST的连带效果源码 apisix/plugins/forward-auth.lua 显示当request_method为POST时插件除了转发请求体还会把客户端的Content-Length、Expect、Transfer-Encoding、Content-Encoding等与实体相关的请求头原样透传给认证服务保证大体积请求体的正确传输。测试用例 t/plugin/forward-auth.t 专门用 11MB 的请求体验证了这一行为。allow_degradation的降级语义它不是超时降级而是指网络层完全不可达httpc:request_uri返回nil时跳过认证注意它并不会让认证服务返回 5xx 时放行请求。status_on_error只作用于网络错误从源码 apisix/plugins/forward-auth.lua 看该配置仅在request_uri调用失败如连接被拒、超时时生效若认证服务正常返回了 HTTP 响应哪怕是 5xx则按其真实状态码处理。HTTPS 场景的 schema 校验check_schema中调用了core.utils.check_https与check_tls_bool见 apisix/plugins/forward-auth.luauri必须为合法的http://或https://地址ssl_verify必须是布尔值非法配置会在提交时直接被拒绝。数据定义APISIX 自动生成的转发请求头无论你是否配置request_headersAPISIX 都会自动生成并发送以下 5 个请求头给认证服务见 apisix/plugins/forward-auth.luaSchemeHTTP MethodHostURISource IPX-Forwarded-ProtoX-Forwarded-MethodX-Forwarded-HostX-Forwarded-UriX-Forwarded-For它们分别取自当前请求的协议core.request.get_scheme、HTTP 方法core.request.get_method、Hostcore.request.get_host、原始 URIctx.var.request_uri和客户端真实 IPcore.request.get_remote_client_ip让认证服务能够感知原始请求的上下文。一个值得注意的覆盖规则源码 apisix/plugins/forward-auth.lua 表明request_headers中指定的客户端请求头不会覆盖上述 APISIX 自动生成的X-Forwarded-*头代码通过if not auth_headers[header]做了去重保护。这一点在测试用例 t/plugin/forward-auth.t 中有明确验证即使客户端伪造了X-Forwarded-Host: apisix.apache.org认证服务收到的仍是 APISIX 计算出的真实 Host。快速上手从零搭建外部认证链路第一步准备认证服务你可以用任何 HTTP 服务充当认证服务。文档示例使用 Apache APISIX 的serverless-pre-function插件详见 docs/zh/latest/plugins/serverless.md在网关内部模拟一个认证端点/auth:::note 先从conf/config.yaml中取出admin_key存入环境变量deployment.admin.admin_key相关配置见 conf/config.yamladmin_key$(yq .deployment.admin.admin_key[0].key conf/config.yaml | sed s///g):::curl -X PUT http://127.0.0.1:9180/apisix/admin/routes/auth \ -H X-API-KEY: $admin_key \ -H Content-Type: application/json \ -d { uri: /auth, plugins: { serverless-pre-function: { phase: rewrite, functions: [ return function (conf, ctx) local core require(\apisix.core\); local authorization core.request.header(ctx, \Authorization\); if authorization \123\ then core.response.exit(200); elseif authorization \321\ then core.response.set_header(\X-User-ID\, \i-am-user\); core.response.exit(200); else core.response.set_header(\Location\, \http://example.com/auth\); core.response.exit(403); end end ] } } }这个模拟认证服务实现了三类响应恰好覆盖了forward-auth的三种结果处理路径Authorization: 123→ 返回200认证通过Authorization: 321→ 返回200并附带响应头X-User-ID: i-am-user用于演示认证服务响应头转发到上游其他情况 → 返回403并附带Location: http://example.com/auth用于演示认证失败时向客户端返回自定义响应头。第二步在目标 Route 上启用插件在需要保护的 Route/headers上挂载forward-authcurl -X PUT http://127.0.0.1:9180/apisix/admin/routes/1 \ -H X-API-KEY: $admin_key \ -d { uri: /headers, plugins: { forward-auth: { uri: http://127.0.0.1:9080/auth, request_headers: [Authorization], upstream_headers: [X-User-ID], client_headers: [Location] } }, upstream: { nodes: { httpbin.org:80: 1 }, type: roundrobin } }这里配置的语义是request_headers: [Authorization]把客户端的Authorization头透传给认证服务upstream_headers: [X-User-ID]认证通过时把认证服务返回的X-User-ID头拼接到转发给上游的请求上client_headers: [Location]认证失败时把认证服务返回的Location头原样带回给客户端用于 302/403 重定向场景。第三步三种方式验证效果方式一请求头携带认证信息认证通过curl http://127.0.0.1:9080/headers -H Authorization: 123{ headers: { Authorization: 123, Next: More-headers } }请求被放行到上游 httpbin.orgAuthorization头原样透传。方式二认证服务响应头转发到 Upstreamcurl http://127.0.0.1:9080/headers -H Authorization: 321{ headers: { Authorization: 321, X-User-ID: i-am-user, Next: More-headers } }认证服务返回的X-User-ID: i-am-user被成功注入到上游请求中上游业务方可直接读取该头获取用户身份。方式三认证失败返回自定义响应curl -i http://127.0.0.1:9080/headersHTTP/1.1 403 Forbidden Location: http://example.com/auth注意这里 APISIX 直接以认证服务的403状态和Location头替换了原始响应客户端可据此跳转到统一登录页。client_headers配置项正是在这类场景下发挥作用的。更进阶的用法POST 转发请求体与降级策略POST 模式把请求体交给认证服务当认证逻辑需要解析请求体内容例如校验 JSON 负载中的字段时可将request_method设为POSTcurl -X PUT http://127.0.0.1:9180/apisix/admin/routes/1 \ -H X-API-KEY: $admin_key \ -d { uri: /ping, plugins: { forward-auth: { uri: http://127.0.0.1:9080/auth, request_method: POST, request_headers: [Authorization], upstream_headers: [X-User-ID], client_headers: [Location] } }, upstream: { type: roundrobin, nodes: { 127.0.0.1:1980: 1 } } }测试用例 t/plugin/forward-auth2.t 验证了 POST 模式下Content-Length/Transfer-Encoding/Content-Encoding等实体头会被正确透传给认证服务t/plugin/forward-auth.t 则验证了 POST 模式下upstream_headers与client_headers的转发逻辑依然生效。对于大请求体插件内部优先使用get_client_body_reader()流式读取失败时回退到core.request.get_body()见 apisix/plugins/forward-auth.lua。降级与错误码定制保障认证服务故障时的可用性认证服务不可能永远可用。针对网络故障插件提供了两个互补配置{ forward-auth: { uri: http://127.0.0.1:1984/auth, request_headers: [Authorization], allow_degradation: true, status_on_error: 503 } }status_on_error: 503认证服务网络不可达时向客户端返回503 Service Unavailable而不是默认的403。测试用例 t/plugin/forward-auth.t 验证了该配置生效error_code: 503。allow_degradation: true进一步熔断认证服务不可达时直接跳过认证放行请求测试 t/plugin/forward-auth.t 验证返回200。适合对可用性要求极高、可以容忍认证短暂失效的场景——但请谨慎使用因为它意味着故障期间任何未认证请求都能通过网关。长连接调优forward-auth与认证服务之间默认启用 HTTP 长连接keepalive: true可通过keepalive_timeout空闲超时默认 60000ms与keepalive_pool连接池大小默认 5调节连接复用行为。在高 QPS 场景下合理增大连接池可减少与认证服务之间的 TCP 握手开销若认证服务侧连接回收较快则应相应缩短keepalive_timeout避免网关侧持有大量半死连接。删除插件需要停用forward-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: /hello, plugins: {}, upstream: { type: roundrobin, nodes: { httpbin.org:80: 1 } } }总结与适用边界forward-auth的价值在于解耦认证策略的任何变更算法升级、切换认证供应商、接入统一登录都只发生在外部认证服务上网关配置无需改动。它特别适合已有独立认证中心SSO、OAuth 服务、企业 IdP且希望由网关统一执行认证拦截的场景。同时要注意其边界它属于同步阻塞式认证每个请求都会多一次到认证服务的子请求timeout直接决定认证环节的最长等待时间默认 3srequest_headers/upstream_headers/client_headers均为精确匹配的白名单机制未列入的请求头/响应头不会被转发需按需显式声明与内置认证插件如key-auth、jwt-auth相比它不提供任何本地认证能力完全依赖外部服务的可用性与正确性生产环境务必为认证服务配置高可用并视业务容忍度决定是否开启allow_degradation。完整的 schema 校验逻辑可查阅 apisix/plugins/forward-auth.lua更细粒度的行为包括大请求体、降级、错误码定制、头覆盖规则可参阅测试用例 t/plugin/forward-auth.t 与 t/plugin/forward-auth2.t。【免费下载链接】apisixThe Cloud-Native API Gateway项目地址: https://gitcode.com/GitHub_Trending/ap/apisix创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
