NGINX `ngx_http_auth_request_module` 模块详解基于子请求的认证授权方案
一、背景介绍
在 Web 系统中,我们常常需要根据外部服务(例如单点登录、API 网关、权限中心)的结果来判断用户是否有权限访问某个资源。NGINX 提供的 ngx_http_auth_request_module
模块,正是为这种场景而生。它允许通过向后端发送一个“子请求”来进行授权校验,并根据子请求的返回结果决定是否允许访问主请求。
二、模块简介
ngx_http_auth_request_module
模块从 NGINX 1.5.4 版本引入,并且 默认未编译进 NGINX,需要使用 --with-http_auth_request_module
参数在编译时启用。
该模块的工作机制非常简单高效:
- 如果子请求返回 2xx 响应,表示授权成功,主请求可以继续处理。
- 如果子请求返回 401 或 403,主请求直接返回对应的错误码。
- 其他响应码(如 500、404)则被视为错误。
对于 401 响应,模块还会将子请求的 WWW-Authenticate
响应头透传给主请求的客户端。
三、典型应用场景
- 接入单点登录(SSO)系统
- 与外部权限中心集成
- 与 API 网关配合做细粒度访问控制
- 支持多租户、不同角色的访问权限隔离
四、示例配置
以下是一个常见的配置案例:
location /private/ {auth_request /auth;proxy_pass http://backend;
}location = /auth {proxy_pass http://auth_backend;proxy_pass_request_body off;proxy_set_header Content-Length "";proxy_set_header X-Original-URI $request_uri;
}
解释:
/private/
:需要授权保护的业务路径。/auth
:专门处理授权的子请求路径。proxy_pass_request_body off;
:告诉 NGINX 不将请求体传给授权服务(通常授权不需要请求体)。proxy_set_header Content-Length "";
:清除请求体长度,避免后端误解。proxy_set_header X-Original-URI $request_uri;
:将原始请求 URI 传递给授权服务。
当用户访问 /private/
时,NGINX 会先对 /auth
发起子请求,由授权服务返回是否允许访问。
五、核心指令详解
1. auth_request
语法:
auth_request uri | off;
默认值:off
作用:指定用来授权的子请求 URI。如果设置为 off
,则关闭授权检查。
示例:
auth_request /auth;
2. auth_request_set
语法:
auth_request_set $variable value;
作用:在授权请求完成后,将某个值(通常是子请求返回头部中的值)保存到 NGINX 变量中。
示例:
auth_request_set $auth_status $upstream_http_x_auth_status;
通过这个指令,你可以把子请求返回的 X-Auth-Status
响应头保存到 $auth_status
变量里,用于后续日志、条件判断等。
六、与其他模块结合使用
ngx_http_auth_request_module
可以和其他模块一起用,例如:
- 与
ngx_http_access_module
(IP 限制模块) - 与
ngx_http_auth_basic_module
(基本认证模块) - 与
ngx_http_auth_jwt_module
(JWT 模块)
使用 satisfy
指令灵活组合多重访问控制:
location /private/ {satisfy any;allow 192.168.1.0/24;deny all;auth_request /auth;
}
这段配置的意思是:只要 IP 允许或者授权服务通过,用户就可以访问。
七、最佳实践建议
- 开启缓存:
从 NGINX 1.7.3 开始,可以为授权子请求开启proxy_cache
,大幅降低后端负载。
location = /auth {proxy_cache auth_cache;proxy_cache_valid 200 10m;proxy_cache_valid 401 10m;proxy_pass http://auth_backend;
}
-
减少请求体传输:
使用proxy_pass_request_body off
和proxy_set_header Content-Length ""
,避免向授权后端传递不必要的请求体。 -
传递必要信息:
通过自定义请求头(如X-Original-URI
、X-Forwarded-For
),让授权服务获取更多上下文信息。
八、总结
ngx_http_auth_request_module
是 NGINX 中一颗隐藏的宝石。它小巧灵活,不仅能让 NGINX 支持与外部系统的无缝集成,还能极大提升复杂系统的访问控制能力。通过合理使用这个模块,你可以轻松实现:
单点登录接入
API 网关认证
外部权限系统对接
高性能、高扩展的权限架构