ASP.NET Core CORS request blocked; why doesn't my API apply the right headers?

前端 未结 4 1465
粉色の甜心
粉色の甜心 2021-01-02 10:26

Trying to set up CORS with authentication. I have a Web API site up at http://localhost:61000 and a consuming web application up at http://localhost:62000. In the Web API S

相关标签:
4条回答
  • 2021-01-02 11:02

    In my case the CORS headers were lost because I was making an "application/json" content type request, and in CORS this type of request send first an OPTIONS method, after that, the regular POST is requested. But the OPTIONS was been managed by a Middleware code in my .Net Core pipeline with something like this:

            if (context.Request.Method == "OPTIONS")
            {
                context.Response.StatusCode = (int)HttpStatusCode.OK;
                await context.Response.WriteAsync(string.Empty);
            } 
    

    Once I remove the middleware those requests were flawless attended.

    0 讨论(0)
  • 2021-01-02 11:09

    ASP.NET Core 2.2.0 Answer

    This issue is now fixed. CORS headers are now returned even when exceptions are thrown and a 500 response is returned.

    ASP.NET Core <= 2.1.0 Answer

    CORS Headers were stripped from the response when an exception is thrown and a 500 response is returned.

    0 讨论(0)
  • 2021-01-02 11:10

    I was having this same issue on a Web API project using OWIN middleware, where a wrong package version was causing errors on the API side (hidden on the client side because CORS headers were stripped on the response, which obscured the original error). I implemented a similar solution to yours, sharing here because I could not find any similar example using OWIN on the web:

    using System;
    using System.Linq;
    using System.Threading.Tasks;
    using Owin;
    using Microsoft.Owin;
    using Microsoft.Owin.Cors;
    
    namespace App_Server
    {
        using AppFunc = Func<IDictionary<string, object>, Task>;
        partial class Startup
        {
            public void Configuration(IAppBuilder app)
            {
                app.UseCors(CorsOptions.AllowAll);
                app.Use(new Func<AppFunc, AppFunc>(RetainHeaders));
                ....
                (other startup tasks)
            }
    
            private AppFunc RetainHeaders(AppFunc next)
            {
                AppFunc appFunc = async (IDictionary<string, object> context) =>
                {
                    IOwinContext httpContext = new OwinContext(context);
                    var corsHeaders = new HeaderDictionary(new Dictionary<string, string[]>());
    
                    foreach (var pair in httpContext.Response.Headers)
                    {
                        if (!pair.Key.ToLower().StartsWith("access-control-")) { continue; } //not a CORS header
                        corsHeaders[pair.Key] = pair.Value.First();
                    }
    
                    httpContext.Response.OnSendingHeaders(o =>
                    {
                        var localcontext = new OwinContext((IDictionary<string, object>)o);
                        var headers = localcontext.Response.Headers;
                        //make sure headers are present, and if not, add them back
                        foreach (var pair in corsHeaders)
                        {
                            if (headers.ContainsKey(pair.Key)) { continue; }
                            headers.Add(pair.Key, pair.Value);
                        }
                    }, context);
    
                    await next.Invoke(context);
                };
                return appFunc;
            }
    }
    

    This was a quite a process to work out given how poorly documented the OWIN packages are for .Net, so I hope it helps someone else who comes across it looking for a solution.

    0 讨论(0)
  • 2021-01-02 11:16

    For ASP.NET Core 2.1 and earlier:

    It seems there was an error in my code, but I got the obscure error noted instead of getting an ASP.NET-generated error page. It turns out that the CORS headers are indeed properly applied at first, but then they are stripped off any ASP.NET middleware-generated errors. See also https://github.com/aspnet/Home/issues/2378 .

    I used that link to figure out this class

    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);
            }
        }
    }
    

    And then I added it to my site configuration in Startup.cs:

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            app.UseCors(...);
            app.UseMiddleware<MaintainCorsHeadersMiddleware>();
    
            ...
            app.UseMvc();
        }
    
    0 讨论(0)
提交回复
热议问题