ASP.NET Core CORS请求被阻止;我的API为什么不应用正确的标头?

Pat*_*ski 8 cross-site asp.net-core

尝试通过身份验证设置CORS。我在http:// localhost:61000上有一个Web API网站,在http:// localhost:62000上有一个正在使用的Web应用程序。在Web API Startup.cs中,我具有:

 public void ConfigureServices(IServiceCollection services)
 {
        services.AddCors(o => o.AddPolicy("MyPolicy", corsBuilder =>
        {
            corsBuilder.WithOrigins("http://localhost:62000")
                .AllowAnyMethod()
                .AllowAnyHeader()
                .AllowCredentials();
        }));
        IMvcBuilder builder = services.AddMvc();
        // ...
}

// ...

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
        app.UseCors("MyPolicy");
        app.UseDeveloperExceptionPage();
        app.UseDefaultFiles();
        app.UseStaticFiles();
        app.UseMvc();
}
Run Code Online (Sandbox Code Playgroud)

所有的说明似乎表明这应该是我所需要的。在应用的Javascript中,我调用:

    $.ajax({
        type: 'POST',
        url: "http://localhost:61000/config/api/v1/MyStuff",
        data: matchForm.serialize(),
        crossDomain: true,
        xhrFields: { withCredentials: true },
        success: function (data) {
            alert(data);
        }
    });
Run Code Online (Sandbox Code Playgroud)

我进入Chrome: Failed to load http://localhost:61000/config/api/v1/MyStuff: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:62000' is therefore not allowed access.

...以及在Firefox中: Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:61000/config/api/v1/MyStuff. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).

我想念什么?我认为,这应该是启用CORS所需的全部功能,但显然还有其他不足。

Pat*_*ski 9

对于ASP.NET Core 2.1和更早版本:

似乎我的代码中有一个错误,但是我注意到了一个晦涩的错误,而不是得到一个ASP.NET生成的错误页面。事实证明,CORS标头确实确实在开始时就已正确应用,但随后剥去了任何ASP.NET中间件生成的错误。另请参阅https://github.com/aspnet/Home/issues/2378

我用那个链接弄清楚了这堂课

using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;

namespace MySite.Web.Middleware
{
    /// <summary>
    /// Reinstates CORS headers whenever an error occurs.
    /// </summary>
    /// <remarks>ASP.NET strips off CORS on errors; this overcomes this issue,
    ///  explained and worked around at https://github.com/aspnet/Home/issues/2378 </remarks>
    public class MaintainCorsHeadersMiddleware
    {
        public MaintainCorsHeadersMiddleware(RequestDelegate next)
        {
            _next = next;
        }
        private readonly RequestDelegate _next;

        public async Task Invoke(HttpContext httpContext)
        {
            // Find and hold onto any CORS related headers ...
            var corsHeaders = new HeaderDictionary();
            foreach (var pair in httpContext.Response.Headers)
            {
                if (!pair.Key.ToLower().StartsWith("access-control-")) { continue; } // Not CORS related
                corsHeaders[pair.Key] = pair.Value;
            }

            // Bind to the OnStarting event so that we can make sure these CORS headers are still included going to the client
            httpContext.Response.OnStarting(o => {
                var ctx = (HttpContext)o;
                var headers = ctx.Response.Headers;
                // Ensure all CORS headers remain or else add them back in ...
                foreach (var pair in corsHeaders)
                {
                    if (headers.ContainsKey(pair.Key)) { continue; } // Still there!
                    headers.Add(pair.Key, pair.Value);
                }
                return Task.CompletedTask;
            }, httpContext);

            // Call the pipeline ...
            await _next(httpContext);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在Startup.cs中将其添加到我的站点配置中:

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        app.UseCors(...);
        app.UseMiddleware<MaintainCorsHeadersMiddleware>();

        ...
        app.UseMvc();
    }
Run Code Online (Sandbox Code Playgroud)