IIS劫持了CORS Preflight OPTIONS请求

Bra*_*ham 43 iis asp.net-mvc cors asp.net-web-api

我正在进行CORS POST请求并将Content-Type标头设置为json.这会触发Preflight OPTIONS请求触发(这很好并且预期)

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

我有一个自定义的消息处理程序,它永远不会受到影响,因此在看到ASP.NET之前,IIS会响应请求.

我找到了几个关于这个主题的帖子,他们说了以下内容

  1. 确保卸载/删除/禁用WebDav - 完成

  2. 确保删除/更改OPTIONSVerbHandler以使用aspnet_isapi.dll - 同时尝试

  3. 确保extensionlessURLHandler包含OPTIONS动词 - DONE

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

我能找到的两个最好的帖子听起来像是我的问题

这里:JQuery坚持CORS预检和IIS幽灵响应

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

我尝试在IIS中打开失败请求跟踪(FERB)并将其设置为跟踪所有200个状态代码.我没有看到选项请求被记录...不确定这是否意味着FERB不跟踪OPTIONS请求或者我是否需要更改FERB设置中的某些内容以使其跟踪OPTIONS请求,或者如果这是一条线索我的问题是什么?

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

我已经尝试了我能找到的关于这个主题的所有内容,仍然无法解决我的问题.

帮帮我StackOverflow,你是我唯一的希望.

Tom*_*all 29

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

<modules runAllManagedModulesForAllRequests="true">
    <remove name="WebDavModule" />
</modules>
Run Code Online (Sandbox Code Playgroud)

然后将处理程序设置为以下内容:

<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>
Run Code Online (Sandbox Code Playgroud)

这应该可以解决问题,但如果不这样做,作为最后的手段,您可以强制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>
Run Code Online (Sandbox Code Playgroud)

警惕通配符值,您应该将其设置为您的站点将托管在的域名.

  • 感谢更新。我尝试过这些设置但没有运气。这一切都是“应该”与我所拥有的一起工作的,但有些事情仍然不对。也许问题更多的是“我怎样才能弄清楚是什么在 IIS 中响应了这个请求”? (2认同)
  • 这有点神秘,不是吗.我刚刚做了一些进一步的阅读,发现了一个可能有用的代码片段,将`<remove name ="OPTIONSVerbHandler"/>`添加到`<handlers />`部分. (2认同)

Ana*_*eev 10

经过4个小时的搜索/试验后,这对我有用:

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

  • 使用此方法:<add name ="OPTIONSVerbHandler"path ="*"verb ="OPTIONS"type ="System.Web.Handlers.TransferRequestHandler"resourceType ="Unspecified"requireAccess ="None"/> (4认同)

jde*_*lin 6

我有同样的问题,以下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>
Run Code Online (Sandbox Code Playgroud)

然后我能够在Application_BeginRequest中手动处理CORS OPTIONS请求.

我最初使用此博客文章中详述的库来处理CORS请求.我正在处理的产品要求runAllManagedModulesForAllRequests设置为false.这就是我必须设置自定义实现的原因,但如果您没有这个要求,那么您应该尝试使用该库.当我能够将runAllManagedModulesForAllRequests设置为true时,它工作得很好.


小智 5

我尝试了上述所有建议以及在SO上找到的其他建议,而在我的情况下,最重要的是我们在IIS上启用了请求过滤,并且OPTIONS HTTP动词不在允许的动词列表中。添加完之后,我便可以对其进行整理。

  • 您在哪里添加的? (5认同)

小智 5

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