在Classic ASP的Msxml2.ServerXMLHTTP请求中指定用户/域的问题
解决Classic ASP (JScript)中NTLM认证强制指定域的问题
问题场景
我方站点采用Classic ASP(JScript)对接仅支持NTLM认证的客户API,对方已提供域、用户名和密码,但请求始终返回401未授权。抓包发现认证请求中,指定的用户名被错误处理:反斜杠被移除,且自动添加了本地服务器的域,导致无法通过对方域的认证。
当前使用的代码:
var oXmlHTTP = Server.CreateObject("Msxml2.ServerXMLHTTP.6.0"); oXmlHTTP.open("GET", "EXTERNAL_URL", false, "THEIR_DOMAIN\\THEIR_USER", "PASSWORD"); //var strB64 = base64_encode("THEIR_DOMAIN\\THEIR_USER" + ":" + "PASSWORD"); //oXmlHTTP.setRequestHeader("Authenticate", "NTLM "+strB64); //oXmlHTTP.setRequestHeader("Authorization", "NTLM "+strB64); //oXmlHTTP.setRequestHeader("WWW-Authenticate", "NTLM "+strB64); oXmlHTTP.send(); Response.write(oXmlHTTP.getAllResponseHeaders());
抓包结果显示的异常:
85 3.061152 MY_IP THEIR_IP HTTP 1014 GET EXTERNAL_URL HTTP/1.1 , NTLMSSP_AUTH, User: MYLOCALDOMAIN\THEIR_DOMAINTHEIR_USER
问题原因
Msxml2.ServerXMLHTTP组件默认会优先使用运行ASP的服务器本地域凭证,即使手动指定了第三方域和用户名,也可能被组件自动替换或拼接本地域信息,导致认证凭证不符合对方要求。此外,手动构造NTLM请求头的方式并不符合NTLM的三次握手协议逻辑,无法完成正确认证。
解决方案
改用WinHttp.WinHttpRequest.5.1组件,该组件能更精准地控制NTLM认证的凭证信息,避免本地域的干扰。
完整代码示例
var oWinHttp = Server.CreateObject("WinHttp.WinHttpRequest.5.1"); // 初始化请求 oWinHttp.Open("GET", "EXTERNAL_URL", false); // 关闭自动登录策略,禁止组件自动使用本地服务器凭证 oWinHttp.SetAutoLogonPolicy(0); // 明确指定NTLM认证的域、用户名、密码 // 参数说明:域名、用户名、密码、认证类型(0代表NTLM) oWinHttp.SetCredentials("THEIR_DOMAIN", "THEIR_USER", "PASSWORD", 0); // 发送请求 oWinHttp.Send(); // 输出响应头用于调试 Response.Write(oWinHttp.GetAllResponseHeaders());
关键说明
- 组件替换:
WinHttp.WinHttpRequest.5.1相比Msxml2.ServerXMLHTTP,在跨域NTLM认证场景下的凭证控制更可靠,不会强制注入本地域信息。 - 自动登录策略:
SetAutoLogonPolicy(0)禁用组件的自动登录逻辑,确保使用手动指定的凭证。 - 凭证拆分设置:
SetCredentials方法分别接收域、用户名、密码参数,避免了字符串转义可能带来的错误,同时明确指定认证类型为NTLM。
内容的提问来源于stack exchange,提问作者Code Ninja
相关产品推荐
相关产品推荐

