在为Intranet网页合并NTLM身份验证时,我们遇到了以下问题。
我们的网页代码包含一些在标题
中引用的javascript文件<link rel="stylesheet" type="text/css" href="./jsoneditor.css">
<script type="text/javascript" src="./jsoneditor.js"></script>
<script type="text/javascript" src="./lib/ace/ace.js"></script>
<script type="text/javascript" src="./lib/ace/mode-json.js"></script>
<script type="text/javascript" src="./lib/ace/theme-textmate.js"></script>
<script type="text/javascript" src="./lib/ace/theme-jsoneditor.js"></script>
<script type="text/javascript" src="./lib/jquery.js"></script>
<script type="text/javascript" src="./lib/jsonlint/jsonlint.js"></script>
这些文件中的某些功能稍后会在页面正文中调用。
它是如何正常工作的(没有身份验证)。在打开页面时,会发出index.html的请求,然后是对引用的每个资源的单独请求:
它们按引用顺序处理(您可以看到<script>
标记中的文件顺序与请求顺序相同。.html文件是如何处理的?
因此,请求资源并且解析已停止,直到响应到来。然后它继续执行,如果有的话,并移动到引用的下一个脚本。
因此,如果需要一些需要的命令,例如ace.js需要首先加载jsoneditor.js,这是确保的。
好的,这是一个介绍,现在是NTLM身份验证。它改变了由于NTLM握手而获取资源的方式。它看起来像这样:
1: C --> S GET ...
2: C <-- S 401 Unauthorized, WWW-Authenticate: NTLM
3: C --> S GET ..., Authorization: NTLM <base64-encoded type-1-message>
4: C <-- S 401 Unauthorized, WWW-Authenticate: NTLM <base64-encoded type-2-message>
5: C --> S GET ..., Authorization: NTLM <base64-encoded type-3-message>
6: C <-- S 200 Ok
因此,针对单个资源发送了3个请求,而不是一个。
为什么重要?因为发送外部资源请求的网页解析器并不关心,如果它实际上已经交付,它只是等待响应(在我们的例子中是401)并转移到下一个脚本的加载。最终,所有文件都来了,但是(1)订单没有强制执行,(2)可以运行正文中的函数调用,即使资源尚未到达(成功的200响应)。并且它可能导致抛出javascript异常并且页面未被加载。
您可以看到第一次请求的正确顺序,状态代码为200的响应会混合在一起。
目前我们已经找到了两个解决方案,但没有一个能让我们满意:
不幸的是,NTLM被设计为单独验证每个请求,这使案件稍微复杂化。在我们的方案中,无法将NTLM更改为其他身份验证。
有没有办法以更优雅的方式解决问题?
为了解决这个问题,我们使用.NET HttpListener类作为主机。
答案 0 :(得分:0)
对于s production app,您应该在部署之前运行构建过程,以便在任何情况下连接和缩小脚本。这将消除订单问题,因为它们全部作为一个文件传递,内容按正确的顺序排列。