1

我目前正在开发一个涉及使用 XMLHttpRequest 进行异步文件上传的 Web 应用程序。

当使用 NTLM 身份验证时(这有点必要),异步 POST 最终会被发送两次。第一次响应是 401,第二次是 200。由于 NTLM 的挑战/响应性质,这是我所期望的,但我想知道是否有办法避免发送文件数据两次(特别是因为正在上传的文件可能非常大),可能是通过某种方式首先发送一个空请求以在发送实际数据之前触发 401。

4

2 回答 2

1

在浏览器中,由于 HTTP 和 NTLM 身份验证协议的性质,您无法避免这种情况。

但是,我不认为整个文件的数据实际上被发送了两次。

我将以下内容发送到 IIS 7.5 上受 NTLM 保护的文件:

POST /test/upload HTTP/1.1
Host: localhost
Content-Length: 5
 

请注意,我实际上并没有发送任何内容,只发送了完整的标题。然而,IIS立即做出了回应:

HTTP/1.1 401 Unauthorized
Cache-Control: private
Content-Type: text/html; charset=utf-8
Server: Microsoft-IIS/7.5
WWW-Authenticate: Negotiate
WWW-Authenticate: NTLM
Date: Thu, 10 Jan 2013 05:17:58 GMT
Content-Length: 6277

...

这意味着,如果我是一个上传大文件的浏览器,我会在传输很多字节之前被切断。我假设(希望)任何表现良好的浏览器都会放弃文件上传并开始 HTTP 身份验证。

可能值得你花时间去看看像 Wireshark 这样的东西,看看实际发生了什么。(记得用不同的浏览器进行测试!)不要相信浏览器内的开发者工具,也不要使用像 Fiddler 这样的调试代理。(事实上​​,如果您使用 Fiddler,这实际上可能是问题所在:它会在向服务器发送任何内容之前缓冲整个请求。)

如果您确实发现整个文件确实被完整上传了两次(也许旧版本的 IIS 不发送立即数401?),请考虑事情必须如何发生:

  1. 用户提交上传,导致浏览器向POST服务器发出请求。因为浏览器不可能知道 URL 是否需要身份验证,所以它只会发送完整的请求。

    POST /upload HTTP/1.1
    Content-Type: mutlipart/form-data
    Content-Length: 1024
    
    ...
    
  2. 服务器可能会立即以 响应401,但行为不佳的用户代理无论如何都会传输整个请求。

  3. 一旦请求完成并且浏览器看到了401,我们就开始NTLM 舞蹈。客户端必须发出一个带有Type 1消息的新请求,服务器用另一个响应401,这次包含 Type 2 消息,最后客户端发出第三个请求,带有包含实际凭据的 Type 3 消息。

    由于客户端知道在 NTLM 协商中保证第二个请求是另一个请求401,它知道它可以跳过实体(表单数据)的传输。但是,它必须在第三次请求时第二次发送 post 数据,因为我们必须假设服务器丢弃了原始请求数据。

  4. 我们的文件终于上传了!(但它必须传输两次。)

因此,虽然我认为您不会真正看到 NTLM 身份验证的完整双重上传问题,但您可能仍想消除这种可能性。以下是我将如何处理它:

将上传 URL移到 NTLM 验证区域之外。在上传页面(经过 NTLM 身份验证)上,使用会话 cookie(在加载页面时设置)或发出令牌 - 隐藏字段中的 GUID 就足够了。

接收上传的脚本可以拒绝任何没有有效会话和/或令牌的请求。

如果您使用 NTLM 凭据作为授予对 NTFS 资源的访问权限的机制,则可以将上载写入匿名可写临时文件夹,完成后,将请求重定向到第二个受 NTLM 保护的脚本,该脚本将文件移动到它的目的地。

于 2013-01-10T05:36:03.857 回答
0

不确定您的实现,但看起来其他人在 cURL 和 NTLM 方面遇到了类似的问题。根据下面的链接,您首先提出任何空请求的想法可能会奏效。

通过 NTLM 代理发布文件两次
http://curl.haxx.se/mail/lib-2007-01/0040.html

我正在使用 curl_formadd 和 POST 方法通过 NTLM-auth 代理发送文件。查看 ProgressFunction,我看到我的文件发送了两次(可能是因为特定于 NTLM)。我是对还是错?

你说的对。使用 NTLM 时无法避免这种情况,因为一旦开始传输,我们就无法中止传输。

使用 NTLM/协商代理身份验证的文件上传的不同行为
http://curl.haxx.se/mail/archive-2012-11/0013.html

于 2013-01-10T03:59:49.873 回答