auth_request通过Nginx子请求将鉴权逻辑外移至第三方认证服务,仅依据其返回的2xx/401/403状态码放行或拒绝请求,透传X-Original-URI、Authorization等上下文,配合internal限制和body优化实现安全高效的统一身份认证。

直接用 auth_request 在 Nginx 网关层对接第三方统一身份认证系统,核心是把鉴权逻辑“外移”——Nginx 不自己验 token 或查用户,只做转发和放行判断。整个过程不碰业务代码,也不改后端服务,适合快速接入 OAuth2.0、OIDC、JWT introspection 或自建 auth service。
明确鉴权子请求的职责边界
auth_request 本质是一个“守门人”,它只关心一件事:子请求返回是不是 2xx。其他所有逻辑(比如解析 Authorization 头、调用 /token/introspect、校验 scope、检查白名单)都由你指定的认证服务完成。Nginx 只需透传必要上下文:
- 用
X-Original-URI和X-Original-Method告诉认证服务“用户想访问什么” - 用
Authorization或Cookie头原样透传原始凭证(如 Bearer token 或 session cookie) - 加
internal限制/auth路径不可被外部直连,防绕过 - 关闭子请求 body:
proxy_pass_request_body off+proxy_set_header Content-Length "",避免重复解析或超时
对接主流第三方认证服务的典型配置
不同认证系统对子请求接口要求略有差异,但 Nginx 配置模式高度一致:
-
OAuth2.0 Token Introspection(如 Keycloak、Auth0):子请求走 POST 到
https://auth.example.com/oauth2/introspect,透传token参数或 Authorization 头,认证服务返回{"active": true, "scope": "read:api"} -
OIDC UserInfo Endpoint:需先确保已有 valid ID token,子请求带
Authorization: Bearer <id_token></id_token>访问https://auth.example.com/userinfo,成功即视为已登录 -
JWT 直接校验(轻量场景):Nginx 不推荐硬编码密钥验签,更稳妥的是 proxy_pass 到一个极简 Flask/FastAPI 服务,由它用公钥或 JWK Set 校验 JWT 并检查
exp、aud、iss
处理认证失败与用户体验
401/403 不能直接返回给前端,否则前端要自己跳登录页;应由 Nginx 主动重定向:
- 定义
error_page 401 =302 https://auth.example.com/login?redirect_uri=$scheme://$host$request_uri; - 若需支持 Cookie 登录态(如 SSO 子域名共享),在
/auth子请求中透传Cookie头,并确保认证服务能识别该 Cookie 对应的会话 - 避免缓存登录页:在
/auth_pagelocation 中加add_header Cache-Control "no-store, no-cache";
关键安全细节不能漏
看似简单,但几个配置点出错会导致绕过或泄露:
-
location = /auth必须加internal,否则攻击者可伪造请求绕过鉴权 - 子请求 URL 若含敏感参数(如 client_secret),必须用
proxy_pass内部转发,禁止拼接在return 302中暴露 - 透传头信息时,显式清空可能被篡改的头:
proxy_set_header X-Forwarded-User "";防止客户端伪造 - 建议开启
auth_request_timeout 5s;和auth_request_buffering off;,防认证服务慢拖垮网关

















