Nginx 身份验证请求意外状态 404

问题描述 投票:0回答:3

当子请求发送到 nginx auth_request 模块时,我收到以下错误。 作为信息,我开发了一个基于 Spring Security 的 Web 应用程序,其中仅包含一种 Web 方法,即进行身份验证以验证用户凭据和会话,并以 200 或 401 错误代码进行响应。

成功验证页面重定向到主页 url 后,该 url 将显示上游应用程序的主页,但我在 nginx 日志中收到此错误,其状态如下

错误 身份验证请求意外状态:发送到客户端时出现 404,客户端:127.0.0.1,服务器:,请求:“GET / HTTP/1.1”,主机:“localhost:8180”,引用者:“https://localhost:8180/登录.html"*

此错误表明 nginx 已将完整请求的 url 传递给 auth 子请求,而不是“/authenticate”,并且 auth 服务会查找在其中找不到的资源并抛出 404 错误。

    server {
    listen    8180 ssl;
    ssl_certificate         certs/nginx.pem;
    ssl_certificate_key     certs/nginx.pem;

    location /{
        proxy_set_header xclnt "ap1";  
        auth_request /authenticate;
        proxy_pass https://adi-backend;         
    }

    location = /authenticate {
        proxy_set_header xclnt "ap1";  
        proxy_pass http://authserv;
    }

    location = /login.html {
        root   html;
    }

    location = /50x.html {
        root   html;
    }
    error_page   500 502 503 504  /50x.html;
    error_page  401 403 login.html;
}
authentication nginx runtime-error http-status-code-404
3个回答
5
投票

文档说不支持从

http://authserv
返回状态404 Not Found。
ngx_http_auth_request_module
只需 2xx、401 或 403:

如果子请求返回2xx响应码,则允许访问。如果返回401或403,则表示访问被拒绝,并显示相应的错误代码。 子请求返回的任何其他响应代码都被视为错误。

编写 auth 模块的人显然认为 404 意味着无法找到 auth 端点本身,例如身份验证请求发送到了错误的 URL。而不是请求的东西不存在。

因此,如果您不希望日志中出现这些错误,请使用 auth 模块以外的其他内容。 ...

...也许是Lua?这就是我正在做的事情,当我希望“auth”处理程序既进行身份验证,又检查请求的内容是否存在时:

这是我的 Lua 方法(效果很好):

location ~ ^/-/u/([^/][^/]+/)(.*)$ {

  # (1. There's Nginx's http_auth_request_module module, but it handles upstream 404 Not Found
  # as an internal error. So it cannot both do auth, and check does-it-exist? at the same time.
  # 2. ngx.location.capture is synchronous, but non-blocking: the code execution stops, until
  # a response is received — but meanwhile, the nginx worker continues with other things.)
  set $publSiteId $1;
  set $hashPath $2;
  access_by_lua '
    response = ngx.location.capture("/_auth_upload/" .. ngx.var.publSiteId .. "/" .. ngx.var.hashPath)
    if response.status == 404 then
      ngx.status = 404
      ngx.say("Not found. [TyNGXFKB604]")
      return ngx.exit(ngx.OK)
    end
    if response.status == 401 or response.status == 403 then
      ngx.status = response.status
      ngx.say("Access denied. [TyNGX5KWA2]")
      return ngx.exit(ngx.OK)
    end';

  alias /opt/talkyard/uploads/public/$2;
  ... cache headers ...
}

这是 Nginx 子请求处理程序:

location /_auth_upload/ {
  # Only for Nginx subrequests.
  internal;
  proxy_pass              http://app:9000/-/auth-upload/;
  proxy_pass_request_body off;
  proxy_set_header        Content-Length "";
  proxy_set_header        X-Original-URI $request_uri;
}

完整来源这里。我希望这有帮助:-)


3
投票

这可能对某人有帮助...... 就我而言,改变

location = /authenticate {
        proxy_set_header xclnt "ap1";  
        proxy_pass http://authserv;
    }

location = /authenticate {
        proxy_set_header xclnt "ap1";  
        proxy_pass http://authserv/;
    }

(proxy_pass 中 URL 末尾的斜杠)解决了问题...


0
投票

一般回应:

我希望文档能够指出 auth_request 会触发 GET 请求,我花了六个小时徒劳地尝试了大量 GPT。

如果在任何情况下有人在 auth_request 路由中使用 POST,请确保将其更改为 GET,标头中的令牌(例如

Authorization: Bearer xyz-etc
)在 GET 请求中工作得很好。

© www.soinside.com 2019 - 2024. All rights reserved.