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

Posted

技术标签:

【中文标题】在提琴手工作之前,CORS 预检请求不会命中 IIS【英文标题】:CORS preflight request doesn't hit IIS until fiddler is working 【发布时间】:2021-07-07 21:24:42 【问题描述】:

是的,这是另一个 CORS 问题,我为这个问题搜索了超过三天,试图了解发生了什么。

在此 repo 下找到的示例应用程序 Sample Application

我正在使用托管在本地 IIS 中的 ASP.net Core 2.2,启用了 Windows 身份验证并禁用了匿名身份验证。 配置为允许 CORS。

 services.AddCors(options =>
        
            options.AddPolicy("AllowOrigin",
                builder => builder               
                          .SetIsOriginAllowed(origin => true)                        
                          .AllowAnyMethod()
                          .AllowAnyHeader()
                          .AllowCredentials()
            );
        );

为了处理预检请求,我创建了自定义中间件

private Task BeginInvoke(HttpContext context)
    
        if (context.Request.Method == "OPTIONS")
        
            if (!string.IsNullOrEmpty( context.Request.Headers["Origin"]) )
                context.Response.Headers.Add("Access-Control-Allow-Origin", new[]  (string)context.Request.Headers["Origin"] );
            context.Response.Headers.Add("Access-Control-Allow-Headers", new[]  "foo,Access2, Origin, X-Requested-With, Content-Type, Accept,authentication" );
            context.Response.Headers.Add("Access-Control-Allow-Methods", new[]  "GET, POST, PUT, DELETE, OPTIONS" );
            context.Response.Headers.Add("Access-Control-Allow-Credentials", new[]  "true" );


            context.Response.StatusCode = 200;
            return Task.CompletedTask; //context.Response.WriteAsync("OK");
                  
        return _next.Invoke(context); //complete request pipline 
    

当我尝试发送带有客户标头的复杂请求时(预检请求)(请求 A)

fetch('http://localhost:8050/api/values',credentials:'include', headers:'foo':'foo')
.then(response => response.json())
.then(data => console.log(data));

我遇到了一个错误

这就是请求在提琴手中的方式,(供您参考,此请求不会到达 ASP.Net 应用程序,只是点击 IIS)

激活提琴手然后创建一个简单的从浏览器(chrome)到端点('http://localhost:8050/api/values)的get请求时最有趣的事情,它会产生三次认证握手并成功
    => 401 => 401 => 200

如fiddler所示(就是

然后,如果我再次尝试复杂的请求(请求 A)(第一次导致错误),它作为两个请求没有任何问题
    响应为 200(succeded)的预检请求(OPTIONS 动词) 实际请求(GET 动词),所需响应为 200(succeded

这里是提琴手分析

我的问题

    为什么在激活 fiddler 时一个简单的 get 请求(来自 chrome)解决了我的所有问题,并允许我在此之后发出任何复杂的 CORS 请求而不会出现任何错误。 我如何可以毫无问题地发出复杂的 CORS 请求(无需提琴手)。

请注意,我正在考虑(可能是错误的)Fiddler 充当处理 IIS 的代理,并且可以在 IIS 接受任何复杂请求后进行所需的身份验证握手。

在此 repo 下找到的示例应用程序 Sample Application

【问题讨论】:

blogs.iis.net/iisteam/getting-started-with-the-iis-cors-module 如果没有该模块,则无需进一步讨论。 有没有考虑过chrome浏览器的原因,有没有试过其他浏览器?如果给chrome添加一些cors扩展,或许可以解决这个问题。如果你想在asp.net core中启用cors,可以参考这个链接:Enable Cross-Origin Requests (CORS) in ASP.NET Core. @LexLi 但我想处理 CORS 抛出 ASP.NET 应用程序而不是我的 IIS 服务器? 你想要的不切实际。阅读该博客文章中的“使用 Windows 身份验证”以了解更多信息。 【参考方案1】:

我找到了解决问题的方法: Lex Li 建议它与 IIS CORS 模块有关

IIS 中的 CORS 部署到 IIS 时,如果服务器未配置为允许匿名访问,则 CORS 必须在 Windows 身份验证之前运行。为了支持这种情况,需要为应用安装和配置 IIS CORS 模块。

通过从IIS CORS Module 安装 IIS CORS 模块

对于 IIS CORS 模块文档IIS CORS documentation

感谢 Lex Li的支持

【讨论】:

以上是关于在提琴手工作之前,CORS 预检请求不会命中 IIS的主要内容,如果未能解决你的问题,请参考以下文章

Angular 4 call couchdb有CORS错误,但提琴手中没有出现预检

是否有可能在 CORS 之前进行 CSRF 攻击?

Safari不会在Apache上的Vue.js应用程序中加载预检CORS身份验证请求(XHR)

从服务工作者发送的 CORS 预检请求,但不是来自常规请求

CORS 请求预检请求,以用户代码结尾

使用 Django 和 Angular 的 CORS 预检请求