在 Internet Explorer 上使用 Windows 身份验证通过 SSL 进行跨域 ajax 调用失败

Posted

技术标签:

【中文标题】在 Internet Explorer 上使用 Windows 身份验证通过 SSL 进行跨域 ajax 调用失败【英文标题】:cross domain ajax call over SSL with windows auth fails on Internet Explorer 【发布时间】:2012-11-16 10:09:12 【问题描述】:

我有一个使用 Windows 身份验证的 Web 应用程序,该应用程序在我们的 Intranet 上的不同服务器上使用 Windows 身份验证调用 Web 服务。具体来说,我正在使用带有 SSL 的 jQuery 跨域对 WCF 休息服务 (WebHttpBinding) 进行 ajax 调用。

我通过在 Web 服务中设置 Access-Control-Allow-Origin 标头解决了跨域问题。在 jquery 调用中,即通过设置$.support.cors = true;

我已经通过设置标题("Access-Control-Allow-Credentials", "true")解决了发送凭证的问题;在 web 服务和 jQuery 调用中通过设置

$.ajaxSetup( xhrFields:  withCredentials: true, crossDomain: true

        
    );

我在 IE 和 Chrome 上都使用了此功能,使用在不同服务器上运行的 Windows 身份验证从 Web 应用程序使用 Windows 身份验证创建跨域到 Web 服务。但是,当我将 SSL 添加到双方(https 到 https)时,该调用在 IE 中不再有效。它继续在 Chrome 中运行。

查看 Fiddler 中的 http 流量,似乎浏览器甚至没有发出请求,也就是说,Fiddler 根本没有表明请求已经发出的条目。通过调试 javascript,我可以捕获从 jquery 调用返回的错误,并且状态文本是“访问被拒绝”。但正如我所说,在我看来,浏览器甚至没有将请求发送到 Web 服务。

我尝试了一个 jquery cors 插件jQuery.XDomainRequest.js。那时我开始在 fiddler 中看到 http 调用。这是一个单一的 401“拒绝访问”。就是这样。客户端调用似乎没有发送任何凭据。

在此之前,在我添加 SSL 之前,我会看到一个 401,其中包含身份验证凭据的响应标头。随后是 200,其中请求标头包含 Windows 身份验证凭据。所以它奏效了。

但现在(在 IE 中)我只收到了单个 401。所以我卡住了,我需要拨打电话

    跨域, 使用 Windows 身份验证, 使用 SSL 和 使用 IE。

我可以将所有四个要求组合在一起。我很困惑为什么我可以使用 windows auth 跨域来使用 IE,但是当我添加 SSL 时我无法让它工作。

它在 Chrome 中运行良好,因此它必须与 XDomainRequest 对象有关。有什么方法可以调整 jQuery 调用以使这一切正常工作。有没有人听说过这个特定的问题?这是可以克服的吗?还是我只是用头撞墙?

【问题讨论】:

【参考方案1】:

XDomainRequest 明确禁止使用身份验证;请参阅此处的#5:http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx

不清楚JQuery跨域调用在IE9及以下如何工作,不支持通过XDomainRequest对象的CORSexcept。在 IE10 中,这应该可以正常工作。

【讨论】:

【参考方案2】:

也许 OP 的问题只是一个 IE9 问题,但我在现代浏览器中也遇到了一些麻烦。我发现如果您需要 Windows 身份验证才能工作,则不能将 * 用于 Access-Control-Allow-Origin 标头。

跨域服务器(ajax 请求的目标)需要在Access-Control-Allow-Origin header 中完整指定宿主服务器(ajax 调用来自的域)。

也许 OP 正在这样做,但对我来说,这是缺失的部分。我现在有 jQuery ajax,带有 xhrFields: withCredentials: true 和通常的 CORS 标头,它适用于 IE11、https、windows auth、跨域。它也适用于其他浏览器。它适用于 get 和 post。

我遇到的另一个问题...我只在“OPTIONS”请求上设置我的 CORS 标头,但这有时不起作用,所以我现在只是将这些标头添加到每个请求中。我只是将这些添加到我的 ASP.NET MVC Application_BeginRequest 方法中,如下所示。

HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "https://portal");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Credentials", "true");

这是JavaScript端的sn-p

$.ajax(
    url: "<a url in here>"
    type: "POST",
    xhrFields: 
      withCredentials: true
    ,
    contentType: "application/json",
    data: payload,
    success: success,
    error: function (data) 
        logFailure(data);
    
);

【讨论】:

以上是关于在 Internet Explorer 上使用 Windows 身份验证通过 SSL 进行跨域 ajax 调用失败的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 JavaScript 显示“此网站需要 Internet Explorer”?

网站无法在 Internet Explorer 上运行

Flash 在 Internet Explorer 上覆盖厚框

在同一台计算机上运行 Internet Explorer 6、Internet Explorer 7 和 Internet Explorer 8

css 在Internet Explorer上隐藏滚动条

如何使此 Google 字体在 Internet Explorer 11 上运行