用于IOS和Windows Firefox的WEB API CORS jQuery Ajax 401

时间:2014-09-17 14:48:24

标签: jquery asp.net-mvc iis asp.net-web-api cors

我在iOS Safari / Chrome或Windows 7 Firefox客户端通过jQuery AJAX发出CORS请求时看到401响应,但是从IE / Chrome Windows 7客户端发出请求时却没有。

我有一个ASP.NET MVC 5应用程序,它使用诸如

之类的URL调用托管在我企业域中的IIS 8.5服务器上的Web Api 2.2服务

mvc.mydom.com

api.mydom.com

两个站点都设置为需要Windows身份验证。

MVC应用程序使用jQuery Ajax命令向API服务发出请求

    $.ajax({
        dataType: "json",
        url: http:'//api.mydom.com/Cars/1',
        beforeSend: function (xhr) {
            xhr.withCredentials = true;
        },
        xhrFields: {
            withCredentials: true
        },
        success: function (data) {
             //Do stuff
            });
        },
        error: function (xhr, ajaxOptions, thrownError) {
             //alert stuff
            }
     });

在我的Web API应用程序中,我按如下方式启用CORS支持:

 // configured by application start

config.EnableCors();
config.SetCorsPolicyProviderFactory(new CorsPolicyFactory());

public class CorsPolicyFactory : ICorsPolicyProviderFactory
{
   ICorsPolicyProvider provider = new MisCorsPolicyProvider();

   public ICorsPolicyProvider GetCorsPolicyProvider(System.Net.Http.HttpRequestMessage request)
   {
       return this.provider;
   }
}

public class MisCorsPolicyProvider : ICorsPolicyProvider
{
    private CorsPolicy policy;

    public MisCorsPolicyProvider()
    {
        this.policy = new CorsPolicy
        {
            AllowAnyMethod = true,
            AllowAnyHeader = true,
            SupportsCredentials = true
        };

        this.policy.Origins.Add("http://mvc.mydom.com");
    }

    public Task<CorsPolicy> GetCorsPolicyAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        return Task.FromResult(this.policy);
    }
}

想知道这是否是预检请求的问题我遇到了几个引用,这些引用表明IIS 8.5需要对Web Config进行以下更改。

替换

<system.webServer>
  <handlers>  
    <remove name="OPTIONSVerbHandler"/>
  </handlers>  
<system.webServer>

<system.webServer>
  <handlers>  
    <remove name="OPTIONS"/>
  </handlers>  
<system.webServer>

没有任何帮助。

在iOS和Firefox Windows上查看开发人员工具中的请求我看不到传递的凭据,但我在Windows IE / Chrome中看到了。

错误的标头/响应示例如下:

GET http://api.mydom.com/Cars/1 HTTP/1.1
Host: api.mydom.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:29.0) Gecko/20100101 Firefox/29.0
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: en-gb,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://mvc.mydom.com/Home/Index
Origin: http://mvc.mydom.com
Connection: keep-alive

RESPONSE

HTTP/1.1 401 Unauthorized
Content-Type: text/html
Server: Microsoft-IIS/8.5
WWW-Authenticate: Negotiate
X-Powered-By: ASP.NET
Date: Wed, 17 Sep 2014 14:25:49 GMT
Content-Length: 1293
Proxy-Support: Session-Based-Authentication

在Windows IE / Chrome网络配置文件中,我看到401错误,然后是200响应所需的资源。这不会发生在iOS或赢得Firefox上,这使我相信它可能与预检请求失败有关,但请求是GET不是OPTIONS。我假设预检请求是OPTIONS

挣扎着看我错过了什么想法?

更新

好吧我认为可能是因为Firefox和我认为Safari和iOS正确实现了W3C规范,该规范规定预检请求不应传递用户凭据;由于IIS设置为需要Windows身份验证,因此请求失败并显示401.2错误。 IE,Chrome似乎继续进行验证并因此成功。所以我想有一种方法可以关闭OPTIONS请求的Windows身份验证吗?

1 个答案:

答案 0 :(得分:0)

注意到许多人在他们的Web API受到Windows身份验证等保护时遇到了401错误。 CORS预检请求不包含凭据,因此即使在ASP.NET接触之前,IIS也会使用401.2进行响应。

一个肮脏的解决方法是编写HTTP模块并挂钩到IIS管道,该管道在HttpApplication.BeginRequest事件上注册,此模块返回预检请求的预期200响应。

此解决方法仅适用于IIS 7+集成模式。

您可以阅读包含更多详细信息的my blog post