Windows Server 2016上的IIS 10 + ASP.NET Core 6 = CORS问题

0sgqnhkj  于 2023-05-18  发布在  Windows
关注(0)|答案(2)|浏览(277)

我的问题是如何配置IIS网站托管ASP.NET应用程序以允许任何跨域请求?现在的细节:
我有一个ASP.NETCore应用程序(实际上是JSON服务),它会被其他来源不同的Web应用程序调用。这当然会触发CORS错误。我能够解决CORS错误,而它是在Kestrel运行。我至少有两种方法是工作-一个看起来像这样:

builder.Services.AddCors(options =>
    {
        options.AddDefaultPolicy(
                          policy =>
                          {
                              policy
                                .AllowAnyOrigin()
                                .AllowAnyMethod()
                                .AllowAnyHeader();
                          });
    });
    ...
    app.UseCors();

另一个看起来像这样:

app.Use((context, next) =>
    {
        context.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
        context.Response.Headers.Add("Access-Control-Allow-Headers", new[] { "Origin, X-Requested-With, Content-Type, Accept" });
        context.Response.Headers.Add("Access-Control-Allow-Methods", new[] { "GET, POST, PUT, DELETE, OPTIONS" });
        context.Response.Headers.Add("Access-Control-Allow-Credentials", new[] { "true" });
        if (context.Request.Method == "OPTIONS")
        {
            context.Response.StatusCode = 200;
            return context.Response.WriteAsync("OK");
        }
        // Call the next delegate/middleware in the pipeline.
        return next(context);
    });

两者都可以工作,但现在我需要在IIS下托管同一个应用程序。所以我加载了“托管捆绑包”创建了一个网站,将其指向发布的应用程序,根据文档(https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/iis/?view=aspnetcore-7.0)它自己工作,但当从另一个来源调用时,我得到CORS错误。开箱即用的错误是Access-Control-Allow-Origin头丢失(即使ASP.NET应用程序添加了它)。
所以我在IIS上添加自定义头文件,如下所示

<httpProtocol>
        <customHeaders>
            <add name="Access-Control-Allow-Origin" value="*" />
            <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
            <add name="Access-Control-Allow-Headers" value="Origin, X-Api-Key, X-Requested-With, Content-Type, Accept, Authorization" />
            <add name="Access-Control-Allow-Credentials" value="true" />
        </customHeaders>
    </httpProtocol>

现在不是关于Access-Control-Allow-Origin missing的错误,我得到了一个说它有2个值。因此,我删除了ASP.NET应用程序中添加这些头的代码,但保留了在IIS中添加这些头的xml。现在我得到一个CORS错误,关于预检请求没有得到状态200。据我所知,preflight请求发送OPTION,只要它返回200(就像我在C#中所做的那样)就可以了。它只需要在IIS上,因为它没有进入ASP.NET应用程序。在查看类似的问题时,我尝试了很多方法-在web.config中使用各种xml,并一度重定向到OPTION,但到目前为止都没有效果
似乎相关的内容是x1c 0d1x
我试过用

<handlers>
    <remove name="OPTIONSVerbHandler" />

这也无济于事。底线是

*当IIS没有Access-Control-Allow-Origin标头时,无论ASP.NET应用程序有什么,我都会得到“missing Access-Control-Allow-Origin header”
*当IIS有Access-Control-Allow-Origin头,而ASP.NET也有,我得到一个错误,有2个,只允许一个
*当IIS有Access-Control-Allow-Origin头而ASP.NET没有时,我得到一个错误,即preflight请求没有获得200状态

我尝试的最新事情是在IIS上安装和配置CORS模块,这也不起作用。见评论

xkrw2x1b

xkrw2x1b1#

根据评论,我能够通过CORS。谢谢samwu和Lex Li。
必须在IIS上安装CORS模块,并将其添加到网站的**web.config*<system.webServer>* 标签内:

<cors enabled="true">
    <add origin="*">
        <allowHeaders allowAllRequestedHeaders="true" />
        <allowMethods>
            <add method="GET" />
            <add method="HEAD" />
            <add method="POST" />
            <add method="PUT" /> 
            <add method="DELETE" />
            <add method="OPTION" />             
        </allowMethods>
    </add>      
  </cors>

来自这两个很棒的人的评论的有用链接:

安装https://www.iis.net/downloads/microsoft/iis-cors-module
配置https://blogs.iis.net/iisteam/getting-started-with-the-iis-cors-module
但是然后我遇到了一个非常奇怪的小故障,我在一个URL上得到了404,该URL通过将源URL和目标URL连接在一起而构建错误。它只发生在应用程序在IIS下使用此配置时,而不是在Kestrel下,所以我仍然责怪IIS,无法解决这个问题

qaxu7uf2

qaxu7uf22#

在遇到IIS CORS模块的404问题后(请参阅我的其他答案),并仔细查看了preflight请求的外观,我发现我能够在ASP.NET代码中克服它,如下所示:

app.Use((context, next) =>
{
    context.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
    context.Response.Headers.Add("Access-Control-Allow-Headers", new[] { "Origin, X-Requested-With, Content-Type, Accept, additional-header" });
    context.Response.Headers.Add("Access-Control-Allow-Methods", new[] { "HEAD, GET, POST, PUT, DELETE, OPTIONS" });
    context.Response.Headers.Add("Access-Control-Allow-Credentials", new[] { "true" });
    if (context.Request.Method == "OPTIONS")
    {
        context.Response.StatusCode = 200;
        return context.Response.WriteAsync("OK");
    }
    // Call the next delegate/middleware in the pipeline.
    return next(context);
});

与我在问题中发布的内容相比,重要的变化是

context.Response.Headers.Add("Access-Control-Allow-Headers"

现在包含

additional-header

在列表中
如果您查看配置IIS CORS模块链接中的说明:https://blogs.iis.net/iisteam/getting-started-with-the-iis-cors-module
您将看到preflight请求是一个带有OPTION方法的请求,它发送这个头(“additional-header”),因此通过将它添加到允许的头中,我就能够向它发送答案。该链接告诉您正确的答案是状态204,这是错误的。当我尝试时,浏览器抱怨它没有得到200,所以我把它切换回200,然后它工作了。
我没有从机器上删除IISCORS模块的安装,但我删除了web.config中的配置。
我不确定安装它是否是解决方案的一部分(可能是)。

相关问题