web-dev-qa-db-fra.com

Demande ASP.NET Core CORS bloquée; pourquoi mon API n'applique-t-elle pas les bons en-têtes?

Essayer de configurer CORS avec authentification. J'ai un site Web API sur http: // localhost: 61000 et une application Web consommatrice sur http: // localhost: 62000 . Dans l'API Web Startup.cs, j'ai:

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

Toute la tendance semble indiquer que cela devrait être tout ce dont j'ai besoin. Dans le code Javascript de mon application, j'appelle:

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

Et je reçois dans 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.

... et dans 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). 

Qu'est-ce que je rate? C’était tout ce dont j'avais besoin pour activer la SCRO, pensai-je, mais il est clair qu’il manque quelque chose.

4
Patrick Szalapski

Il semble qu'il y ait eu une erreur dans mon code, mais j'ai noté l'erreur obscure au lieu d'une page d'erreur générée par ASP.NET. Il s’avère que les en-têtes CORS sont bien appliqués d’abord, mais ils sont ensuite supprimés de toute erreur générée par le middleware ASP.NET. Voir aussi https://github.com/aspnet/Home/issues/2378 .

J'ai utilisé ce lien pour comprendre cette classe

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

Et puis je l'ai ajouté à la configuration de mon site dans Startup.cs:

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

        ...
        app.UseMvc();
    }
4
Patrick Szalapski

Dans mon cas, les en-têtes CORS ont été perdus parce que je faisais une demande de type de contenu "application/json" et, dans CORS, ce type de demande envoie d'abord une méthode OPTIONS, après quoi le POST normal est demandé. Mais les OPTIONS ont été gérées par un code middleware dans mon pipeline .Net Core avec quelque chose comme:

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

Une fois que j'ai supprimé le middleware, ces demandes ont été suivies sans faille. 

0
Fidel Orozco

Réponse ASP.NET Core 2.2.0

Ce problème est maintenant corrigé . Les en-têtes CORS sont maintenant renvoyés même lorsque des exceptions sont générées et qu'une réponse 500 est renvoyée.

ASP.NET Core <= 2.1.0 Réponse

Les en-têtes CORS ont été supprimés de la réponse lorsqu'une exception est générée et qu'une réponse 500 est renvoyée.

0