1

I'm trying to make a local post request from a static HTML file to an ASP.NET Core 2.2 Web API. CORS middle-ware is working fine, I can do a simple get request. I ultimately need to make this post request from within a chrome extension. I've been using ASP.NET since the beginning, this is my first attempt at a Core solution, I'm boggled by all the hurdles to overcome, especially this one. Is there something wrong with my Fetch syntax?

Here's my CORS configuration based on this: https://enable-cors.org/server_aspnet.html

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddCors();

        services.AddMvc()
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_2));
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        app.UseCors(builder => builder.WithOrigins("*"));

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });
    }
}
fetch call in local static html file:
fetch ('http://localhost:49828/Bookmark', {
    method: 'post',
    headers:{'Content-Type': 'application/json'},
    body: JSON.stringify({ ID: 0, Name: 'google', URL: 'google.com', Tags: '' })
})

here's the raw request from Fiddler:
OPTIONS http://localhost:49828/Bookmark HTTP/1.1
Host: localhost:49828
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Access-Control-Request-Method: POST
Origin: null
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36
Access-Control-Request-Headers: content-type
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9

console log from chrome:
Access to fetch at 'http://localhost:49828/Bookmark' from origin 'null' has been blocked by CORS policy: Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response.

console log from firefox:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:49828/Bookmark. (Reason: missing token ‘content-type’ in CORS header ‘Access-Control-Allow-Headers’ from CORS preflight channel).
richardsonwtr
  • 153
  • 5
  • 16
Scott
  • 23
  • 6
  • You ned to update your ASP.Net CORS configuration to send back an Access-Control-Allow-Headers response header that includes 'content-type' in its value. I’m not sure how to do that with the server code you’re using, but if I think you’ll find something if you search the existing answers here for "ASP.Net Access-Control-Allow-Headers". – sideshowbarker Apr 02 '19 at 01:42
  • I followed the code from this site, they seem like an authority on the subject. Know of any other authority with correct information? https://enable-cors.org/server_aspnet.html – Scott Apr 02 '19 at 13:20

1 Answers1

0

It's been a while, but I am not sure that .WithOrigins("*") is a valid way to wildcard everything. Have you tried using .AllowAnyOrigin() instead? Even better (from a security standpoint), use WithOrigins with the actual host of where the HTML file is hosted). If that is local, then it would be the localhost address you are serving the HTML page from (which I assume is different than you API).

So something like (where 1234 is the actual local port you are hosting the HTML from).

app.UseCors(builder => builder.WithOrigins("https://localhost:1234"));

If AllowAnyOrigin() works for testing, fine. But don't use it in production. Microsoft considers this an insecure configuration (see https://learn.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-2.2#set-the-allowed-origins). Always used named origins in prod.

Bryan Lewis
  • 5,629
  • 4
  • 39
  • 45
  • I might have more of a design problem on my hand here. I want to execute this call from a Chrome extension, meaning anywhere. Limiting to a few domains obviously is not what I'm looking for. How do people writing Chrome extensions update data to a web server? This seems like such a common thing to do. What am I missing? – Scott Apr 01 '19 at 23:37
  • I made this change as suggested: app.UseCors(builder => builder.WithOrigins("http://localhost:49828") .AllowAnyMethod() .AllowCredentials() .AllowAnyHeader()); Here's my response from Visual Studio Debig window: Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 OPTIONS http://localhost:49828/Bookmark Microsoft.AspNetCore.Cors.Infrastructure.CorsService:Information: CORS policy execution failed. Microsoft.AspNetCore.Cors.Infrastructure.CorsService:Information: Request origin null does not have permission to access the resource. – Scott Apr 01 '19 at 23:43
  • I don't have any experience with Chrome extensions, so I'm afraid I can't help you there. You have a bit of a hybrid design issue, since the extension is running in the browser and subject to CORS security requirements, but it's "hosted" locally within the extension and not from a specific domain. As a side note, be sure to include the protocol for the WithOrigins statement (add an http to the beginning). – Bryan Lewis Apr 01 '19 at 23:59