为什么 NGINX 对多部分文件上传请求的验证会立即关闭连接?

Why does NGINX authverify of multipart file upload request receive an immediate closed connection?

NGINX 在 8080 上为我们的网关提供服务,通过我们在 8100 上的 AAA 服务器进行身份验证,然后将经过身份验证的请求传递到 8081 上的 NGINX 进行路由。除了针对我们的文件服务器的文件上传请求(任何大小)之外,一切都可以直接开箱即用。发送到8080的Gateway,强制关闭8100到AAA的连接时出现500 Internal Server Error。发送到 8081,NGINX 路由多部分文件上传内容就好了。

改变client_max_body_size没有帮助;也不会更改 keep-alive 值。在 NGINX 中执行 multipart 验证步骤的技巧是什么?


server {
    listen 8080;
    listen [::]:8080;
    server_name _;
    access_log /var/log/nginx/api.auth.log;

    location = /authverify {
        internal;
        proxy_pass http://127.0.0.1:8081/api/v1/aaa/authentication/validate;
        proxy_pass_request_body off;
        proxy_set_header Content-Length "";
        proxy_set_header X-Original-URI $request_uri;
    }

    location /api/v1/aaa/authentication {
    proxy_pass http://127.0.0.1:8081;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

    location /api {
        auth_request /authverify;
        auth_request_set $auth_header $upstream_http_authorization;
        more_set_headers "Authorization: $auth_header";

        proxy_pass http://127.0.0.1:8081;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

非常感谢任何帮助! (我们是 运行 nginx 1.6.2,没有安装额外的模块。)

更新: 似乎 WEB API 对请求 header 在内容已被抑制时仍然指示 "multipart" 不满意。我已经研究过在身份验证请求中抑制 Content-Type 但没有找到令人满意的实现方法...

2019-11-22 05:20:41.896 +00:00 [Error] The server encountered an internal error and was unable to process your request. Try it again. System.IO.IOException: Unexpected end of Stream, the content may have already been read by another component. at Microsoft.AspNetCore.WebUtilities.MultipartReaderStream.ReadAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken) at Microsoft.AspNetCore.WebUtilities.StreamHelperExtensions.DrainAsync(Stream stream, ArrayPool1 bytePool, Nullable1 limit, CancellationToken cancellationToken) at Microsoft.AspNetCore.WebUtilities.MultipartReader.ReadNextSectionAsync(CancellationToken cancellationToken) at Microsoft.AspNetCore.Http.Features.FormFeature.InnerReadFormAsync(CancellationToken cancellationToken) at Microsoft.AspNetCore.Mvc.ModelBinding.FormValueProviderFactory.AddValueProviderAsync(ValueProviderFactoryContext context) at Microsoft.AspNetCore.Mvc.ModelBinding.CompositeValueProvider.CreateAsync(ActionContext actionContext, IList`1 factories) at Microsoft.AspNetCore.Mvc.ModelBinding.CompositeValueProvider.CreateAsync(ControllerContext controllerContext) at Microsoft.AspNetCore.Mvc.Internal.ControllerBinderDelegateProvider.<>c__DisplayClass0_0.<g__Bind|0>d.MoveNext()

就我而言,重新设置 Content-Type 解决了问题:

    location = /authverify {
        internal;
        proxy_pass http://127.0.0.1:8081/api/v1/aaa/authentication/validate;
        proxy_pass_request_body off;
        proxy_set_header Content-Length "";
        proxy_set_header Content-Type "";
        proxy_set_header X-Original-URI $request_uri;
    }

但这可能取决于您的 API 处理请求的方式。