wake-up-neo.com

Aktivieren Sie den OPTIONS-Header für CORS in der .NET Core-Web-API

Ich habe dieses Problem gelöst, nachdem ich auf Stackoverflow keine Lösung gefunden habe. Daher teile ich mein Problem hier und die Lösung in einer Antwort.

Nach dem Aktivieren einer domänenübergreifenden Richtlinie in meiner .NET Core-Web-API-Anwendung mit AddCors funktioniert sie in Browsern immer noch nicht. Dies liegt daran, dass Browser, einschließlich Chrome und Firefox), zuerst eine OPTIONS-Anfrage senden und meine Anwendung nur mit 204 No Content antwortet.

16
Niels Brinch

Fügen Sie Ihrem Projekt eine Middleware-Klasse hinzu, um das Verb OPTIONS zu behandeln.

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

namespace Web.Middlewares
{
    public class OptionsMiddleware
    {
        private readonly RequestDelegate _next;

        public OptionsMiddleware(RequestDelegate next)
        {
            _next = next;
        }

        public Task Invoke(HttpContext context)
        {
            return BeginInvoke(context);
        }

        private Task BeginInvoke(HttpContext context)
        {
            if (context.Request.Method == "OPTIONS")
            {
                context.Response.Headers.Add("Access-Control-Allow-Origin", new[] { (string)context.Request.Headers["Origin"] });
                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" });
                context.Response.StatusCode = 200;
                return context.Response.WriteAsync("OK");
            }

            return _next.Invoke(context);
        }
    }

    public static class OptionsMiddlewareExtensions
    {
        public static IApplicationBuilder UseOptions(this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<OptionsMiddleware>();
        }
    }
}

Fügen Sie dann app.UseOptions(); this als erste Zeile in Startup.cs in der Configure-Methode hinzu.

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    app.UseOptions();
}
21
Niels Brinch

Ich weiß, dass es beantwortet wurde. Antworten Sie einfach mit den aktualisierten Informationen. Also würde es anderen helfen.

Es ist jetzt in asp.net Core Framework eingebaut.

Folgen Sie einfach https://docs.Microsoft.com/en-us/aspnet/core/security/cors

und ersetzen

    app.UseCors(builder =>
   builder.WithOrigins("http://example.com"));

mit

        app.UseCors(builder =>
       builder.WithOrigins("http://example.com")
              .AllowAnyHeader()
              .AllowAnyMethod()
              .AllowCredentials());
5
Jeyara

Das hat bei mir funktioniert:

Stellen Sie sicher, dass dies:

app.UseCors(builder => {
    AllowAnyOrigin()
    AllowAnyMethod()
    AllowAnyHeader()
});

Tritt vor einem der folgenden Ereignisse auf:

app.UseHttpsRedirection();
app.UseDefaultFiles();
app.UseStaticFiles();
app.UseCookiePolicy();

Denken Sie daran, wir haben es mit einer "Pipeline" zu tun. Das cors Zeug muss zuerst sein.

-gimzani

1
user1628627

Es ist keine zusätzliche Middleware erforderlich. Wie oben bereits erwähnt, ist nur die in der Cors-Konfiguration zulässige OPTIONS-Methode erforderlich. Sie können AllowAnyMethod wie hier vorgeschlagen: https://stackoverflow.com/a/55764660/1192191

Aber es ist sicherer, nur das Folgende zuzulassen:

app.UseCors(builder => builder
.WithOrigins("https://localhost", "https://production.company.com") /* list of environments that will access this api */
.WithMethods("GET", "OPTIONS") /* assuming your endpoint only supports GET */
.WithHeaders("Origin", "Authorization") /* headers apart of safe-list ones that you use */
);

Einige Header sind immer erlaubt: https://developer.mozilla.org/en-US/docs/Glossary/CORS-safelisted_request_header

0

Ich wollte dies für eine einzelne Methode zulassen und keine Middleware verwenden, um dies für jede Methode zuzulassen. Dies ist, was ich getan habe:

Manuelle Behandlung der 'OPTIONS'-Methode

[HttpOptions("/find")]
public IActionResult FindOptions()
{
    Response.Headers.Add("Access-Control-Allow-Origin", new[] { (string)Request.Headers["Origin"] });
    Response.Headers.Add("Access-Control-Allow-Headers", new[] { "Origin, X-Requested-With, Content-Type, Accept" });
    Response.Headers.Add("Access-Control-Allow-Methods", new[] { "POST, OPTIONS" }); // new[] { "GET, POST, PUT, DELETE, OPTIONS" }
    Response.Headers.Add("Access-Control-Allow-Credentials", new[] { "true" });
    return NoContent();
}
[HttpPost("/find")]
public async Task<IActionResult> FindOptions([FromForm]Find_POSTModel model)
{
    AllowCrossOrigin();

    // your code...
}

private void AllowCrossOrigin()
{
    Uri Origin = null;
    Uri.TryCreate(Request.Headers["Origin"].FirstOrDefault(), UriKind.Absolute, out Origin);

    if (Origin != null && IsOriginAllowed(Origin))
        Response.Headers.Add("Access-Control-Allow-Origin", $"{Origin.Scheme}://{Origin.Host}");
}

Und natürlich können Sie IsOriginAllowed nach Belieben implementieren

private bool IsOriginAllowed(Uri Origin)
{
    const string myDomain = "mydomain.com";
    const string[] allowedDomains = new []{ "example.com", "sub.example.com" };

    return 
           allowedDomains.Contains(Origin.Host) 
           || Origin.Host.EndsWith($".{myDomain}");
}

Weitere Informationen finden Sie unter Aktivieren von CORS für POST Anforderungen auf einem einzelnen Endpunkt

0
Jean