【问题标题】:Nginx auth request unexpected status 404Nginx 身份验证请求意外状态 404
【发布时间】:2018-07-25 01:05:34
【问题描述】:

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

认证成功后页面被重定向到显示上游应用程序主页的主页 url,而不是我在 nginx 日志中收到此错误,如下所示

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

此错误表明 nginx 已将完整请求的 url 传递给 auth subrequest 而不是“/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


    【解决方案1】:

    The docs 表示不支持从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;
    }
    

    完整来源here。我希望这会有所帮助:-)

    【讨论】:

      【解决方案2】:

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

      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 末尾的斜线)解决了这个问题...

      【讨论】:

        猜你喜欢
        • 2015-08-26
        • 2017-02-01
        • 2021-08-02
        • 2015-06-21
        • 2014-01-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多