Home > Back-end >  Missing "Access-Control-Allow-Methods" header for CORS in IIS Express
Missing "Access-Control-Allow-Methods" header for CORS in IIS Express

Time:09-23

I know similar questions have been asked many times but after hours of using any suggestion I can find it still does not resolve.

This is ASP.Net Core 3.1 web app which serves a web API, which I need to have accessible in development with Visual Studio - usual debug mode which runs IIS Express. Another web app is accessing the API (both on localhost, but different port numbers). GET and POST works, PUT does not work.

I know that no preflight requests get sent for GET, HEAD and POST requests, so the error seems to occur only when IIS (or Asp.Net?) has to handle the preflight request.

Browser shows the error

    Access to ... from origin ... has been blocked by CORS policy: Method PUT
    is not allowed by Access-Control-Allow-Methods in preflight response.

Both the preflight request and the actual PUT request are being performed, visible in the browser, but fail.

The response headers of the preflight request contain:

    access-control-allow-headers: *
    access-control-allow-origin: *

They NEVER contain an "access-control-allow-methods" header, no matter what I tried. It seems obvious that the PUT request won't work because the preflight request SHOULD contain this header with "PUT" specified as allowed method.

What I Tried

  1. Controlling CORS from AspNetCore web app

(This would require that the preflight request actually reaches the app and isn't caught by IIS and never forwarded - which I don't know, however)

Installed Microsoft.AspNetCore.Mvc.Cors package, then in Startup.cs:

        services.AddCors(options => 
        {
            options.AddDefaultPolicy(
                policy =>
                {
                    policy.WithOrigins("http://localhost:8080").AllowAnyMethod().AllowAnyHeader();
                });
        });

plus the corresponding UseCors() entry lower in Startup.cs (after Routing and before Authorization, as it should be).

Also tried

     services.AddCors();

in services, and then the following in the Configure section:

        app.UseCors(x => x
            .AllowAnyMethod()
            .AllowAnyHeader()
            .SetIsOriginAllowed(origin => true) // allow any origin
            .AllowCredentials()); // allow credentials

Same result - no "access-control-allow-methods" header.

  1. IIS Express configuration

In case IIS is doing the preflight job, it should be configurable directly there.

Curiously, IIS Express has 5 locations with configuration files:

  • C:\Users<username>\Documents\IISExpress\config\
  • C:\Program Files\IIS Express (x86)\config\templates\PersonalWebServer\
  • C:\Program Files\IIS Express (x86)\AppServer\
  • C:\Program Files\IIS Express\config\templates\PersonalWebServer\
  • C:\Program Files\IIS Express\AppServer\

None of these contained anything related to CORS in my case (but the two headers shown above nevertheless show). So I tried adding custom headers:

    <httpProtocol>
        <customHeaders>
            <clear />
        <add name="access-control-allow-origin" value="*" />
        <add name="access-control-allow-headers" value="*" />
    <add name="access-control-allow-methods" value="GET,POST,PUT,PATCH,DELETE,OPTIONS" />
       </customHeaders>
        <redirectHeaders>
            <clear />
        </redirectHeaders>
    </httpProtocol>

I added these to EVERY "applicationhost.config" file in above locations. Same result - nothing changes.

  1. web.config in AspNet Core web app

     <system.webServer>
       <httpProtocol>
         <customHeaders>
           <add name="Access-Control-Allow-Origin" value="http://localhost:8080" />
           <add name="Access-Control-Allow-Methods" value="GET,PUT,POST,DELETE" />
           <add name="Access-Control-Allow-Headers" value="*" />
    

Same result.

(I did restart the computer after every one of these changes, just for good measure.)

At this stage, I am out of options.

Why would 3 different ways to configure CORS have literally NO EFFECT on what the server sends at all?

Is there a way to find out whether the preflight request gets handled by IIS or by ASP.NET Core? At least then I would know where I have to put the configuration.

CodePudding user response:

Thanks to the comment of LexLi I found my own answer.

My use case was, as mentioned for Visual Studio debugging to work with CORS, and for that, there is yet another location for a IIS-Express configuration file:

    $(SolutionDir)\.vs\$ProjectName)\config

I put the above-mentioned custom header lines into this file (plus an additional "access-control-max-age" header).

This alone did not work - the C# UseCors() code in the web app was needed as well. Then it works perfectly.

So in fact my code was all correct - just missing know-how on VS.

I agree with Lex Li that one should rather use the IIS CORS module - yet this has to be configured and IIS Express does not provide a config tool.

CodePudding user response:

try this, it will allow requests from any origin, any header, any method.

options.AddDefaultPolicy(
            policy =>
            {
                policy.AllowAnyOrigin()
                    .AllowAnyHeader()
                    .AllowAnyMethod();
            });

check if you have disabled CORS in Action Metod or Controller

  • Related