将 NTLM 凭据传递给远程 Web 服务

Posted

技术标签:

【中文标题】将 NTLM 凭据传递给远程 Web 服务【英文标题】:Passing NTLM credentials to remote web service 【发布时间】:2013-09-13 13:17:07 【问题描述】:

我想。

我从rm1.domain.com 加载我的页面,并在其javascript 中调用rm2.domain.com 上的Web 服务。

我希望被调用的 Web 服务能够读取进行调用的用户的 NTLM 凭据,但我遇到了一些问题。

场景 A(不起作用)

如果我的配置文件中有以下内容:

 <webHttpEndpoint>
        <standardEndpoint name="" 
         automaticFormatSelectionEnabled="true" 
         crossDomainScriptAccessEnabled="true">
          <security>
            <transport clientCredentialType="Ntlm"></transport>
          </security>
       </standardEndpoint>
 </webHttpEndpoint>

并且只有在 IIS 中启用了 Windows 身份验证,我得到了预期:

场景 B(不起作用)

我的配置文件中有以下内容

<webHttpEndpoint>
  <standardEndpoint name="" automaticFormatSelectionEnabled="true">
      <security>
        <transport clientCredentialType="Ntlm"></transport>
      </security>
  </standardEndpoint>
</webHttpEndpoint>

以及我的 JavaScript 中的以下内容:

jQuery.ajax(
    url: "http://rm2.domain.com/getInfo?name=bobsyouruncle,
    dataType: "json",
    async: false,
    success: function(data) 
        console.log('woot');
    ,
    error: function(ex) 
        console.log(ex);
    
);

只有在 IIS 中启用了 Windows 身份验证,浏览器才会抛出:

获取http://rm2.domain.com/getInfo?name=bobyouruncle 401 (未经授权)jquery-1.10.1.min.js:6 XMLHttpRequest 无法加载 http://rm2.domain.com/getInfo?name=bobyouruncle。来源http://rm1 是 Access-Control-Allow-Origin 不允许。 jquery-1.10.1.min.js:6

如果我将我的 JavaScript 更改为 JSONP,那么我也什么也得不到,但这并不意外,因为我从 web.config 中删除了 crossDomainScriptAccessEnabled="true"。但正如您将在场景 C 中看到的那样,您不能让 crossDomainScriptAccessEnabled="true" 启用身份验证方案。

场景 C(不会通过凭据)

如果mr2的web服务的web.config类似场景B,IIS匿名认证开启(windows认证关闭),jQuery请求JSONp,则服务返回数据,但认证信息不通过。

底线 (TL;DR) 有没有办法让我的 web 服务保持匿名 IIS,在其 web.config 中使用跨域标记,从浏览器传递域 (NTLM) 凭据并在我的 web 服务的代码隐藏中解析它们。

文档和数量之多令人难以理解。

【问题讨论】:

“有没有办法让我的 Web 服务作为 IIS 匿名 [并且] 从浏览器传递域 (NTLM) 凭据” - 据我所知。跨度> 好像没有,看看:***.com/questions/7902938/…。此外,您可以尝试实现您的 CORS 替代方案:blogs.microsoft.co.il/blogs/idof/archive/2011/07.aspx 和 blogs.msdn.com/b/carlosfigueira/archive/2012/05/15/… 尝试将 ajax 更改为帖子。 【参考方案1】:

如果您查看像提琴手这样的检查器中的流量,客户端和服务器之间是否发生了正确的握手?启用 Windows 身份验证后,服务器会发出一个响应,其中包含一个标头,指示客户端(浏览器)应发送服务器接受的 NTLM 令牌并继续做出实际响应。

如果您在同一个域上托管 Web 服务,您可能能够隔离听起来像是两个问题的问题,以解决凭证问题,一旦这工作正常,您就可以专注于 CORS 问题。

为了部分回答您的问题,经过身份验证的匿名网站不会请求 NTLM(或 Kerberos)令牌

【讨论】:

【参考方案2】:

看看这个,关于 NTLM 和模拟的使用有一些有趣的观点。

The HTTP request is unauthorized with client authentication scheme 'Ntlm'

我知道您的问题不是 WCF 特定的,但提出的一些问题与您的方案完全相关。

最后一条评论说“authenticationScheme 和 proxyAuthenticationScheme 到“Ntlm”对你来说很有趣。

【讨论】:

【参考方案3】:

抱歉,我不知道您要传递什么样的数据,但如果唯一的问题是跨域 ajax 调用,只需在将执行 ajax 的目标域上放置一个新的 html 文件代表调用页面调用。

当您想要进行 ajax 调用时,将新的 iframe 插入到指向 iframe 位置的文档中,并在查询字符串中传递数据。

函数发送数据(数据) var datastring=JSON.stringify(data); 变量 el=document.createElement("iframe"); el.src="//rm2.domain.com/iframe.html?data="+encodeURIComponent(datastring); if(el.style)el.style.display="none"; document.body.appendChild(el);

iframe 接收数据,进行 ajax 调用,然后通过 URL 片段将值发送回原始页面:

<!DOCTYPE html>
<html lang="en-US">

<head>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript">
if(document.referrer=="rm1.domain.com" )
    var querystring=window.location.search.split("&");
    var datastring="";
    var data;
    for(var q=0;q<querystring.length;q++)
        if(querystring[q].split("=")[0]=="data")datastring=querystring[q].slice("data".length+1);
    
    if(datastring)data=JSON.parse(datastring);

    jQuery.ajax(
        url: "/getInfo?name=bobsyouruncle",
        dataType: "json",
        data:data,
        async: false,
        success: function(data) 
            top.location="#data="+JSON.stringify(data);
        ,
        error: function(ex) 
            top.location="#error="+JSON.stringify(ex);
        
    );

</script>
</head>
</html>

原始页面可以定期检查数据(例如,在添加 iframe 时使用 setInterval 集)。如果需要发送多个请求,也可以传递要清除的间隔的标识符。如果您可以将您的用户群限制在兼容 HTML5 的浏览器中,那么您就有一种不那么“骇人听闻”的方法在 window.postMessage 方法中来回传递数据。所有这些额外的细节都可以在这里找到:http://softwareas.com/cross-domain-communication-with-iframes

【讨论】:

以上是关于将 NTLM 凭据传递给远程 Web 服务的主要内容,如果未能解决你的问题,请参考以下文章

如何在 agora web 中将自定义对象传递给远程流

win7远程连接 您的凭据不工作

Worklight 将登录凭据传递给 iframed 服务器端内容

win10远程连接win7时候连接不上,提示您的凭据不工作是怎么回事?

win10远程桌面访问win7,“你的凭据不工作”

如何从使用 JS 制作的 Windows 8 Native 应用程序将当前 Windows 凭据传递给 WCF REST 服务?