5

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

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 身份验证,浏览器会抛出:

如果我将 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) 凭据并在我的代码隐藏中解析它们我的网络服务。

文档和选项的绝对数量是压倒性的和令人困惑的。

4

3 回答 3

1

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

HTTP 请求未经客户端身份验证方案“Ntlm”授权

我知道您的问题不是 WCF 特定的,但其中一些观点与您的场景无关。

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

于 2013-09-17T12:48:18.367 回答
0

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

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

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

于 2013-09-12T23:30:29.717 回答
0

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

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

函数 sendData(data){ 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

于 2013-09-18T21:46:33.683 回答