title: How to enable CORS in ASP.net Core WebAPI
body: <p><strong>What I am trying to do</strong></p>
  
  <p>I have a backend ASP.Net Core Web API hosted on an Azure Free Plan (Source Code: <a href="https://github.com/killerrin/Portfolio-Backend" rel="noreferrer">https://github.com/killerrin/Portfolio-Backend</a>). </p>
  
  <p>I also have a Client Website which I want to make consume that API. The Client Application will not be hosted on Azure, but rather will be hosted on Github Pages or on another Web Hosting Service that I have access to. Because of this the domain names won't line up. </p>
  
  <p>Looking into this, I need to enable CORS on the Web API side, however I have tried just about everything for several hours now and it is refusing to work.</p>
  
  <p><strong>How I have the Client Setup</strong>
  Its just a simple client written in React.js. I'm calling the APIs through AJAX in Jquery. The React site works so I know its not that. The Jquery API call works as I confirmed in Attempt 1. Here is how I make the calls</p>
  
  <pre><code>    var apiUrl = "http://andrewgodfroyportfolioapi.azurewebsites.net/api/Authentication";
      //alert(username + "|" + password + "|" + apiUrl);
      $.ajax({
          url: apiUrl,
          type: "POST",
          data: {
              username: username,
              password: password
          },
          contentType: "application/json; charset=utf-8",
          dataType: "json",
          success: function (response) {
              var authenticatedUser = JSON.parse(response);
              //alert("Data Loaded: " + authenticatedUser);
              if (onComplete != null) {
                  onComplete(authenticatedUser);
              }
          },
          error: function (xhr, status, error) {
              //alert(xhr.responseText);
              if (onComplete != null) {
                  onComplete(xhr.responseText);
              }
          }
      });
  </code></pre>
  
  <hr>
  
  <p><strong>What I have tried</strong></p>
  
  <hr>
  
  <p><strong>Attempt 1 - The 'proper' way</strong></p>
  
  <p><a href="https://docs.microsoft.com/en-us/aspnet/core/security/cors" rel="noreferrer">https://docs.microsoft.com/en-us/aspnet/core/security/cors</a></p>
  
  <p>I have followed this tutorial on the Microsoft Website to a T, trying all 3 options of enabling it Globally in the Startup.cs, Setting it up on every controller and Trying it on every Action. </p>
  
  <p>Following this method, the Cross Domain works, but only on a single Action on a single controller (POST to the AccountController). For everything else, the <code>Microsoft.AspNetCore.Cors</code> middleware refuses to set the headers.</p>
  
  <p>I installed <code>Microsoft.AspNetCore.Cors</code> through NUGET and the version is <code>1.1.2</code></p>
  
  <p>Here is how I have it setup in Startup.cs</p>
  
  <pre><code>    // This method gets called by the runtime. Use this method to add services to the container.
      public void ConfigureServices(IServiceCollection services)
      {
          // Add Cors
          services.AddCors(o =&gt; o.AddPolicy("MyPolicy", builder =&gt;
          {
              builder.AllowAnyOrigin()
                     .AllowAnyMethod()
                     .AllowAnyHeader();
          }));
  
          // Add framework services.
          services.AddMvc();
          services.Configure&lt;MvcOptions&gt;(options =&gt;
          {
              options.Filters.Add(new CorsAuthorizationFilterFactory("MyPolicy"));
          });
  
          ...
          ...
          ...
      }
  
      // This method gets called by the runtime. Use this method to configure 
      //the HTTP request pipeline.
      public void Configure(IApplicationBuilder app, IHostingEnvironment env,
      ILoggerFactory loggerFactory)
      {
          loggerFactory.AddConsole(Configuration.GetSection("Logging"));
          loggerFactory.AddDebug();
  
          // Enable Cors
          app.UseCors("MyPolicy");
  
          //app.UseMvcWithDefaultRoute();
          app.UseMvc();
  
          ...
          ...
          ...
      }
  </code></pre>
  
  <p>As you can see, I am doing everything as told. I add Cors before MVC both times, and when that didn't work I attempted putting <code>[EnableCors("MyPolicy")]</code> on every controller as so</p>
  
  <pre><code>[Route("api/[controller]")]
  [EnableCors("MyPolicy")]
  public class AdminController : Controller
  </code></pre>
  
  <hr>
  
  <p><strong>Attempt 2 - Brute Forcing it</strong></p>
  
  <p><a href="https://andrewlock.net/adding-default-security-headers-in-asp-net-core/" rel="noreferrer">https://andrewlock.net/adding-default-security-headers-in-asp-net-core/</a></p>
  
  <p>After several hours of trying on the previous attempt, I figured I would try to bruteforce it by trying to set the headers manually, forcing them to run on every response. I did this following this tutorial on how to manually add headers to every response.</p>
  
  <p>These are the headers I added</p>
  
  <pre><code>.AddCustomHeader("Access-Control-Allow-Origin", "*")
  .AddCustomHeader("Access-Control-Allow-Methods", "*")
  .AddCustomHeader("Access-Control-Allow-Headers", "*")
  .AddCustomHeader("Access-Control-Max-Age", "86400")
  </code></pre>
  
  <p>These are other headers I tried which failed</p>
  
  <pre><code>.AddCustomHeader("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE")
  .AddCustomHeader("Access-Control-Allow-Headers", "content-type, accept, X-PINGOTHER")
  .AddCustomHeader("Access-Control-Allow-Headers", "X-PINGOTHER, Host, User-Agent, Accept, Accept: application/json, application/json, Accept-Language, Accept-Encoding, Access-Control-Request-Method, Access-Control-Request-Headers, Origin, Connection, Content-Type, Content-Type: application/json, Authorization, Connection, Origin, Referer")
  </code></pre>
  
  <p>With this method, the Cross Site headers are being properly applied and they show up in my developer console and in Postman. The problem however is that while it passes the <code>Access-Control-Allow-Origin</code> check, the webbrowser throws a hissy fit on (I believe) <code>Access-Control-Allow-Headers</code> stating <code>415 (Unsupported Media Type)</code></p>
  
  <p>So the brute force method doesn't work either</p>
  
  <hr>
  
  <p><strong>Finally</strong></p>
  
  <p>Has anyone gotten this to work and could lend a hand, or just be able to point me in the right direction?</p>
  
  <hr>
  
  <p><strong>EDIT</strong></p>
  
  <p>So to get the API calls to go through, I had to stop using JQuery and switch to a Pure Javascript <code>XMLHttpRequest</code> format.</p>
  
  <p><strong>Attempt 1</strong> </p>
  
  <p>I managed to get the <code>Microsoft.AspNetCore.Cors</code> to work by following MindingData's answer, except within the <code>Configure</code> Method putting the <code>app.UseCors</code> before <code>app.UseMvc</code>. </p>
  
  <p>In addition, when mixed with the Javascript API Solution <code>options.AllowAnyOrigin()</code> for wildcard support began to work as well.</p>
  
  <p><strong>Attempt 2</strong></p>
  
  <p>So I have managed to get Attempt 2 (brute forcing it) to work... with the only exception that the Wildcard for <code>Access-Control-Allow-Origin</code> doesn't work and as such I have to manually set the domains that have access to it. </p>
  
  <p>Its obviously not ideal since I just want this WebAPI to be wide opened to everyone, but it atleast works for me on a separate site, which means it's a start</p>
  
  <pre><code>app.UseSecurityHeadersMiddleware(new SecurityHeadersBuilder()
      .AddDefaultSecurePolicy()
      .AddCustomHeader("Access-Control-Allow-Origin", "http://localhost:3000")
      .AddCustomHeader("Access-Control-Allow-Methods", "OPTIONS, GET, POST, PUT, PATCH, DELETE")
      .AddCustomHeader("Access-Control-Allow-Headers", "X-PINGOTHER, Content-Type, Authorization"));
  </code></pre>