我想将NTLM凭据传递给远程Web服务。
我从rm1.domain.com
加载我的页面,在其Javascript中,rm2.domain.com
上的网络服务被调用。
我希望调用的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://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服务的代码隐藏中解析它们。
文档和绝对数量的选项令人难以招架。
答案 0 :(得分:0)
如果你看一下像fiddler这样的检查员的流量,客户端和服务器之间是否正确握手?启用Windows身份验证后,服务器将收到一个响应,其中包含一个标头,指示客户端(浏览器)应发送服务器接受的NTLM令牌并继续进行实际响应。
如果您在同一个域上托管Web服务,您可能能够隔离两个问题,以解决凭据问题,一旦工作,您可以专注于CORS问题。
要部分回答您的问题,匿名身份验证的网站将不会请求NTLM(或Kerberos)令牌
答案 1 :(得分:0)
看看这个,对使用NTLM和模仿有一些有趣的观点。
The HTTP request is unauthorized with client authentication scheme 'Ntlm'
我知道您的问题不是特定于WCF的,但有些问题与您的方案无关。
最后评论&#34; authenticationScheme和proxyAuthenticationScheme to&#34; Ntlm&#34;对你来说很有意思。
答案 2 :(得分:0)
抱歉,我不确切知道您尝试传递的数据类型,但如果唯一的问题是跨域ajax调用,只需在目标域上放置一个新的HTML文件即可将代表调用页面执行ajax调用。
如果要进行ajax调用,请在指向iframe位置的文档中插入新的iframe,并将数据传递给查询字符串。
function sendData(data){ var datastring = JSON.stringify(data); var el = document.createElement(&#34; iframe&#34;); el.src =&#34; // rm2.domain.com/iframe.html?data="+encodeURIComponent(datastring); 如果(el.style){el.style.display =&#34;无&#34 ;;} 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标准的浏览器,那么您可以减少&#34; hackish&#34;在window.postMessage方法中来回传递数据的方法。所有这些额外的细节都可以在这里找到:http://softwareas.com/cross-domain-communication-with-iframes