CORS 预检请求返回带有 Windows 身份验证的 HTTP 401

Posted

技术标签:

【中文标题】CORS 预检请求返回带有 Windows 身份验证的 HTTP 401【英文标题】:CORS preflight request returning HTTP 401 with windows authentication 【发布时间】:2016-11-07 04:37:45 【问题描述】:

我在 Google 和 Stack Overflow 上进行了很多搜索以找到解决问题的方法,但没有任何效果。

这是我的问题:

我将 IIS 7 与称为 WebDEV 的特殊编程环境一起使用,该环境不允许直接操作 OPTIONS HTTP 方法。因此,所有建议使用代码进行某种服务器端请求处理的解决方案都是不可行的。

我必须使用 Window 身份验证并禁用匿名访问

我有一个使用 CORS 发布到此服务器的页面。由于此 POST 应该有Content-type: Octet-stream,因此浏览器会发出预检。

当我启用匿名访问时,一切正常(CORS 配置良好)

当我禁用匿名访问时,服务器会回复 HTTP 401 未经授权的预检请求响应,因为它不包含凭据信息。

我试图为 IIS 编写一个接受这样的 OPTIONS 请求的模块,但它不起作用(可能无法将模块正确添加到 IIS)

public class CORSModule : IHttpModule
   

          public void Dispose()  
          

          public void Init(HttpApplication context)
          
               context.PreSendRequestHeaders += delegate
               
                  if (context.Request.HttpMethod == "OPTIONS")
                   
                         var response = context.Response;
                         response.StatusCode = (int)HttpStatusCode.OK;
                   
               ;
          
     

问题是:如何在不启用匿名访问或编写一些服务器端代码的情况下使 IIS 以 HTTP 200 响应预检请求? IIS 是否有一个简单的配置或现成的模块可以做到这一点?至少,将上述模块安装到 IIS 7 中的详细步骤是什么?

【问题讨论】:

【参考方案1】:

web.config 中涉及编写代码、使用重写模块或硬编码值的所有答案在编写时都是正确的,但我相信 2020 年这个问题的正确答案是使用 official IIS CORS module .这将处理所有小问题,例如必须允许未经身份验证的 OPTIONS 请求,而无需支持未经身份验证的用户。

This related answer 有一些关于使用这个模块的非常好的细节,但最简单的配置就在顶部:

  <system.webServer>
    <cors enabled="true">
      <add origin="*" allowCredentials="true" />
    </cors>
  </system.webServer>

我当然会将 origin="*" 更改为您希望从中使用 API 的特定来源。您可以拥有多个 &lt;add&gt; 标记,链接的答案显示如何为每个标记自定义允许的标头、方法等。

【讨论】:

【参考方案2】:

来自 AhmadWabbi 的回答,将 XML 轻松粘贴到您的 web.config 中:

<system.webServer>
    <rewrite>
        <rules>
            <rule name="CORS Preflight Anonymous Authentication" stopProcessing="true">
                <match url=".*" />
                <conditions>
                    <add input="REQUEST_METHOD" pattern="^OPTIONS$" />
                </conditions>
                <action type="CustomResponse" statusCode="200" statusReason="Preflight" statusDescription="Preflight" />
            </rule>
        </rules>
    </rewrite>
</system.webServer>

【讨论】:

【参考方案3】:

这是使用“URL Rewrite”IIS 模块的解决方案。效果很好。

1- 停止 IIS 服务(可能没有必要)

2- 从https://www.microsoft.com/web/downloads/platform.aspx 安装“网络平台安装程序”

3- 转到“应用程序”选项卡并搜索“URL Rewrite”并下载它

4- 安装此修补程序 KB2749660(可能没有必要)

5-打开IIS配置工具,双击“URL Rewrite”

6- 添加新的空白规则

7- 给它起任何名字

8- 在“匹配 URL”中,指定此模式:.*

9- 在“条件”中,指定此条件条目:REQUEST_METHOD 和此模式:^OPTIONS$

10- 在“操作”中,指定:操作类型Personalized response,状态代码200,原因Preflight,描述Preflight

11- 启动服务器

现在,无论身份验证如何,服务器都应该对预检请求回复 200 状态代码响应。

备注:我也禁用了所有压缩,不知道有没有关系。

【讨论】:

救命哥+1 后来微软为 IIS 发布了官方 CORS 模块,docs.microsoft.com/en-us/iis/extensions/cors-module/…,因此不再需要这种解决方法。 @LexLi 好吧,太好了! 有没有人真正设法让 CORS 模块工作?我已经阅读了 100 篇不同的文章,但绝对没有任何效果。如果您启用了 Windows 身份验证,那么执行非常基本的 AJAX 请求似乎是完全不可能的。太荒谬了! @ChrisGilbert 这就是我仍在使用 URL 重写模块的原因 :)【参考方案4】:

为了让您的模块具有优先权,它必须覆盖 IIS 中可能干扰的任何模块。例如,您的 web.config 可能需要或启用匿名,并根据需要创建用于拦截流量和过滤的属性。

【讨论】:

以上是关于CORS 预检请求返回带有 Windows 身份验证的 HTTP 401的主要内容,如果未能解决你的问题,请参考以下文章

在 Angular 2 中使用基本身份验证预检 CORS 请求

使用 Windows 身份验证启用 CORS ASP.NET Web API 2 应用程序中的预检请求

在提琴手工作之前,CORS 预检请求不会命中 IIS

CORS 预检返回 200,但随后的 PUT 从未发生(带有外部 REST API 的 Angular JS)

PouchDB 身份验证触发 CORS 预检请求

为啥经过身份验证的 CORS 请求的预检 OPTIONS 请求在 Chrome 中有效,但在 Firefox 中无效?