IIS劫持CORS预检选项请求

我正在做一个CORS POST请求,并将Content-Type头设置为json。 这触发一个预检选项请求触发(这是好的和预期的)

这个OPTIONS请求以200 OK响应,但这不是来自我的WebAPI应用程序。

我有一个自定义的消息处理程序的地方,它从来没有得到命中,所以这个请求得到了IIS的响应之前,看起来像ASP.NET。

我已经find关于这个问题的几个职位,他们说以下

  1. 确保WebDav已被卸载/删除/禁用 – 完成

  2. 确保将OPTIONSVerbHandler移除/更改为使用aspnet_isapi.dll – TRIED BOTH

  3. 确保extensionlessURLHandler包含OPTIONS动词 – 完成

不过,我的select请求仍然被劫持。 我的意思是,IIS以200 OK响应,但在响应中不包含Access-Control-Allow-Origin标头。 它不包括这个头,因为它永远不会到我的WebAPI CORS代码将设置此标头。

我能find的两个最好的post听起来像我的问题是

在这里: JQuery卡在CORS预检和IIS ghost响应

在这里: http : //brockallen.com/2012/10/18/cors-iis-and-webdav/

我已经尝试启用IIS中的失败请求跟踪(FERB),并将其设置为跟踪所有200个状态代码。 我从来没有看到选项请求被logging…不知道这是否意味着FERB不跟踪OPTIONS请求,或者如果我需要改变FERB设置的东西,使其跟踪OPTIONS请求,或者如果这是一个线索我的问题是什么?

这是在IIS 7.5上运行的ASP.NET WebAPI 2.0(也在IIS 8和IISExpress上testing,结果相同)无论浏览器(Chrome,FF和IE都以相同方式失败)

我已经尝试了一切可以find的主题,但仍然无法解决我的问题。

帮助我StackOverflow,你是我唯一的希望。

有几件事你可以在这里尝试,所有的web.config相关,首先修改你的模块元素以包含属性runAllManagedModulesForAllRequests="true" ,如下所示:

 <modules runAllManagedModulesForAllRequests="true"> <remove name="WebDavModule" /> </modules> 

然后设置你的处理程序如下:

 <handlers> <remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" /> <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" /> <remove name="ExtensionlessUrlHandler-Integrated-4.0" /> <remove name="WebDav" /> <remove name="OPTIONSVerbHandler" /> <add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" /> <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" /> <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /> </handlers> 

这应该做的伎俩,但如果不这样做,作为最后的手段,你可以强制IIS输出正确的标题与下面:

  <system.webServer> <httpProtocol> <customHeaders> <add name="Access-Control-Allow-Origin" value="*" /> <add name="Access-Control-Allow-Methods" value="GET,PUT,POST,DELETE,OPTIONS" /> <add name="Access-Control-Allow-Headers" value="Content-Type" /> </customHeaders> </httpProtocol> </system.webServer> 

要小心通配符值,你应该真的把它设置为你的网站将被托pipe的域名。

这是4个小时的search/实验后为我工作的:

  <handlers> <remove name="OPTIONSVerbHandler" /> <add name="OPTIONSVerbHandler" path="*" verb="OPTIONS" modules="IsapiModule" scriptProcessor="C:\Windows\System32\inetsrv\asp.dll" resourceType="Unspecified" requireAccess="None" /> </handlers> 

我有同样的问题,下面的web.config设置为我解决了这个问题。

  <modules runAllManagedModulesForAllRequests="false"> <remove name="FormsAuthenticationModule" /> </modules> <handlers> <remove name="OPTIONSVerbHandler" /> <remove name="ExtensionlessUrlHandler-Integrated-4.0" /> <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /> </handlers> 

然后,我可以在Application_BeginRequest中手动处理CORS OPTIONS请求。

我最初使用本博客中详细介绍的库来处理CORS请求。 但是,我正在使用的产品要求将runAllManagedModulesForAllRequests设置为false。 这就是为什么我必须build立一个自定义的实现,但如果你没有这个要求,你应该试试这个库。 当我能够将runAllManagedModulesForAllRequests设置为true时,效果很好。

我尝试了以上所有build议以及其他我在SO上find的build议,而且在我的情况下,我们在IIS上启用了请求筛选,OPTIONS HTTP动词不在允许的动词列表中。 一旦我添加了它,我就能够理清其余部分。

我知道这是一个旧的post,但我刚刚经历了完全相同的问题。

在我的情况下,我已经为OWIN和WebAPI安装了CORS。 OWIN CORS中间件在将其调用到WebAPI之前很久就截获了OPTIONS调用。 也许这对未来的其他人很有帮助。

在我们的例子中,是在IIS中根据Web应用程序级别禁用OPTIONS动词的请求过滤。 打开IISpipe理器,单击根应用程序,单击请求过滤,如果OPTIONS出现在列表中删除或允许动词。 希望我先检查了一下,因为浪费了很多时间。

我为我的基于oWin的WebAPI安装了Microsoft.AspNet.WebApi.CorsMicrosoft.Owin.Cors并添加了app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll); 在像下面的configuration:

 public class Startup : IStartup, IAppStartup { public void Configuration(IAppBuilder app) { var config = this.GetInjectionConfiguration(); BootstrapperWebApi bootstrapperWebApi = (BootstrapperWebApi)this.GetBootstrapperWebApi(config); bootstrapperWebApi.Initialize(true) .EnableLogging() .DisableWebApiDefaultExceptionHandler(); WebApiConfig.Register(config); app.UseOwinExceptionHandler(); app.Use<LoggerMiddleware>(); app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll); //others stuff }