Javascript / Ajax NTLM身份validation

我正在开发一个与WebServices通信的HTML5移动应用程序。 WebServices使用NTLM身份validation协议。 我很难通过JavaScript处理握手。 NTLM发送401 unauthorized401 unauthorized作为对我的POST的响应,我没有找到任何回应的方法。

JavaScript可以进行NTLM身份validation吗? 我应该建立一个代理Web服务,例如中间的基本身份validation吗?

我的jQuery调用就像……

 $.ajax({ type: "POST", url: URL, contentType: "text/xml", dataType: "xml", data: soapRequest, username: 'username', password: 'password', xhrFields: { withCredentials: true }, success: processSuccess, error: processError }); 

据我所见,没有人用AJAX实现Windows Integrated / NTLM auth,尽管它应该是可能的(我正在考虑为当前项目将表单身份validation与WindowsTokenRoleProvider结合使用)

基本工作流程应该像这样分解(根据这里和这里的文章):

  1. 在“授权”标题中使用base64编码的type-1 NTLM消息执行GET请求
  2. 将base64编码的type-2 NTLM消息从401响应中的“WWW-Authenticate”标头中取出。
  3. 在上一步收到的noonce上执行NTLM操作(抱歉,我还没有代码示例)
  4. 在“授权”标题中使用base64编码的type-3 NTLM消息执行最终GET。 这应该返回200。

HTTP上的NTLM身份validation更多是使用HTTP的CHAP实现,而不是授权的HTTP请求。

如果我真的开始实现这个,我会更新你。 对不起,我无法提供更多帮助。

您不必响应NTLM(集成Windows身份validation)质询,如果配置正确,您的浏览器应该为您执行此操作。 还可能出现许多其他并发症。

第1步 – 浏览器

检查浏览器是否可以使用NTLM Web应用程序访问和发送您的凭据,或者首先直接点击您正在开发的软件。

第2步 – JavaScript withCredentials属性

当我未能将’withCredentials’属性设置为’true’时,收到的401 Unauthorized错误和描述的症状完全相同。 我不熟悉jQuery,但请确保您尝试设置该属性是成功的。

这个例子对我有用:

 var xhttp = new XMLHttpRequest(); xhttp.open("GET", "https://localhost:44377/SomeService", true); xhttp.withCredentials = true; xhttp.send(); xhttp.onreadystatechange = function(){ if (xhttp.readyState === XMLHttpRequest.DONE) { if (xhttp.status === 200) doSomething(xhttp.responseText); else console.log('There was a problem with the request.'); } }; 

第3步 – 服务器端启用CORS(可选)

我怀疑人们在这个问题上遇到的一个主要原因是他们正在他们的工作站上开发一个组件,其他组件在其他地方托管。 这会导致跨源资源共享(CORS)问题。 有两种解决方案:

  1. 在浏览器中禁用CORS – 最适合开发,最终您的工作将部署在与您的代码访问的资源相同的源上。
  2. 在您的服务器上启用CORS – 在更广泛的互联网上有足够的读数,但这基本上涉及发送启用CORS的标头。

简而言之,要使用凭据启用CORS 您必须:

  • 发送与所提供页面的来源匹配的“Access-Control-Allow-Origin”标题… 这不能是’*’
  • 发送值为’true’的’Access-Control-Allow-Credentials’

这是我在global.asax文件中使用的.NET代码示例。 我认为很容易看到发生了什么,并在需要时翻译成其他语言。

 void Application_BeginRequest(object sender, EventArgs e) { if (Request.HttpMethod == "OPTIONS") { Response.AddHeader("Access-Control-Allow-Methods", "GET, POST"); Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept"); Response.AddHeader("Access-Control-Max-Age", "1728000"); Response.End(); } else { Response.AddHeader("Access-Control-Allow-Credentials", "true"); if (Request.Headers["Origin"] != null) Response.AddHeader("Access-Control-Allow-Origin" , Request.Headers["Origin"]); else Response.AddHeader("Access-Control-Allow-Origin" , "*"); // Last ditch attempt! } } 

问题是你无法通过javascript获取当前登录的域/用户(或者你可以从未找到解决方案)。

如果您已经知道域名,用户名和密码,可以使用https://github.com/erlandranvinge/ntlm.js/tree/master

但是我认为从长远来看,单一登录的这种方法将会令人沮丧。

我们最终在隐藏的iframe中进行NTLM身份validation,并通过javascript访问iframe。

是的NTLM不是很有趣。 但你可能想试试这个, https://github.com/tcr/node-ntlm/blob/master/README.md