Javascript/Ajax NTLM身份验证

Javascript/Ajax NTLM身份验证,javascript,jquery,ajax,web-services,ntlm,Javascript,Jquery,Ajax,Web Services,Ntlm,我正在开发一个HTML5移动应用程序,它可以与WebServices进行通信。Web服务使用NTLM身份验证协议。我很难通过JavaScript处理握手。NTLM将401未经授权作为回复发送到我的帖子,我没有找到任何方式回复 是否可以使用JavaScript进行NTLM身份验证?我是否应该构建一个代理web服务,例如中间包含基本身份验证 我的jQuery调用类似于 $.ajax({ type: "POST", url

我正在开发一个HTML5移动应用程序,它可以与
WebServices
进行通信。Web服务使用NTLM身份验证协议。我很难通过JavaScript处理握手。NTLM将
401未经授权
作为回复发送到我的帖子,我没有找到任何方式回复

是否可以使用JavaScript进行NTLM身份验证?我是否应该构建一个代理web服务,例如中间包含基本身份验证

我的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,尽管这应该是可能的(我正在考虑在当前的项目中将表单身份验证与WindowsTokenRoleProvider相结合)

基本工作流程应该像这样分解(基于文章和):

  • 在中使用base64编码的type-1 NTLM消息执行GET请求 “授权”标题
  • 以base64编码的type-2 NTLM消息为例 从401响应中的“WWW-Authenticate”头中删除
  • 在上一步收到的noonce上执行NTLM操作(很抱歉,我还没有代码示例)
  • 使用“Authorization”标头中的base64编码的type-3 NTLM消息执行最终GET。这应该返回一个200
  • HTTP上的NTLM auth与其说是授权的HTTP请求,不如说是使用HTTP的CHAP实现


    如果我真的着手实施这个,我会告诉你最新情况。对不起,我帮不上什么忙。

    是的,NTLM不是很有趣。但是您可能想试试这个,

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

    如果您已经知道域、用户名和密码,可以使用

    然而,我认为,从长远来看,这种单一登录的方法会令人沮丧


    我们最终在一个隐藏的iframe中执行NTLM身份验证,并通过javascript访问iframe。

    您不必响应NTLM(集成Windows身份验证)挑战,如果配置正确,您的浏览器应该为您执行此操作。此外,还可能出现一些额外的并发症

    步骤1-浏览器

    检查浏览器是否可以通过NTLM web应用程序访问和发送您的凭据,或者先点击您正在开发的软件

    步骤2-带有凭据属性的JavaScript

    当我未能将“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-当您的工作最终将部署在与代码正在访问的资源相同的源上时,这有利于开发
  • 在您的服务器上启用CORS-在更广泛的internet上有大量的阅读,但这基本上涉及到发送启用CORS的头
  • 简而言之,要使用凭据启用CORS,您必须:

    • 发送“访问控制允许来源”标题,该标题与所服务页面的来源相匹配这不能是“*”
    • 发送值为“true”的“访问控制允许凭据”
    这是我的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!
        }
    }
    

    这很好,注意:据我所知,没有一种方法可以使用它来执行CORS(或JSONP)。上面概述的所有四个步骤都应该由浏览器自动完成。我有一个在生产中的工作实现,我如何在我的网站上得到它?当我直接点击服务时,是的,我的浏览器会这样做,并且它会工作。但这并不能阻止我的示例wesite中获取401ed的fetch调用