Enable OPTIONS header for CORS on .NET Core Web API

I solved this problem after I did not find a solution on Stackoverflow, so I share my problem here and the solution in the answer.

After enabling cross-domain policy in my .NET Core Web Api application using AddCors, it still doesn't work in browsers. This is because browsers, including Chrome and Firefox, will first send an OPTIONS request, and my application will simply respond using 204 No Content.

+17
source share
5 answers

Add a middleware class to your project to process the OPTIONS verb .

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

app.UseOptions(); Startup.cs Configure.

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

, . . .

ASP.NET Core.

https://docs.microsoft.com/en-us/aspnet/core/security/cors

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

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

:

, :

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

:

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

, "". Cors .

-gimzani

+3

. , , , OPTIONS, Cors. AllowAnyMethod, : fooobar.com/questions/1669559/...

, :

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 */
);

:https://developer.mozilla.org/en-US/docs/Glossary/CORS-safelisted_request_header

+1

, , . :

Manual processing of the "OPTIONS" method

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

And of course, you can implement IsOriginAllowedas you want

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

You can find more information on how to enable CORS for POST requests on one endpoint.

0
source

Source: https://habr.com/ru/post/1669559/


All Articles