在爲Intranet網頁合併NTLM身份驗證時,我們遇到以下問題。當頁面使用NTLM身份驗證失敗時引用外部腳本
我們的網頁代碼中有頭
<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>
從這些文件中的某些功能在後面的頁面的機構,稱爲引用一些JavaScript文件。
它如何正常工作(無需驗證)。當打開頁面時,就像爲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的響應來混合正確的順序。
目前爲此,我們想出了兩種解決方案,但沒有滿足我們:
- 當執行體JavaScript函數,執行一些延遲(這是不好的做法,肯定)
- 移動所有的javascript代碼都加入到index.html中,而不是引用外部資源,這從代碼的角度來看並不好,但是確保所有東西都按預期運行。
不幸的是,NTLM被設計爲單獨驗證每個請求,這使情況變得複雜一點。在我們的場景中不可能將NTLM更改爲其他身份驗證。
有什麼方法可以更優雅的方式解決問題嗎?
爲了完成這個問題,我們使用.NET HttpListener類作爲我們的主機。
*「發送外部資源請求的網頁解析器並不在意,如果它實際上已經發送或不發送」* - 聽起來像是網頁解析器已損壞。 *「訂單未執行」* - 響應到達的順序從未*在HTTP中執行。 – Tomalak