Yugo Amaryl
Yugo Amaryl

Reputation: 1279

Missing token 'access-control-allow-headers' in CORS header 'Access-Control-Allow-Headers' from CORS preflight channel

I have two VS projects : one exposing MVC5 controllers, the other being an angular client. I want the angular client to be able to query the controllers. I read numerous threads and tried the following :

According to Firebug, this results in the following request :

OPTIONS //Login/Connect HTTP/1.1
Host: localhost:49815
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Origin: http://localhost:50739
Access-Control-Request-Method: POST
Access-Control-Request-Headers: access-control-allow-headers,access-control-allow-origin,content-type
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache

And the following response :

HTTP/1.1 200 OK
Allow: OPTIONS, TRACE, GET, HEAD, POST
Server: Microsoft-IIS/10.0
Public: OPTIONS, TRACE, GET, HEAD, POST
X-SourceFiles: =?UTF-8?B?RDpcVEZTXElVV2ViXEdhcE5ldFNlcnZlclxBU1BTZXJ2aWNlc1xMb2dpblxDb25uZWN0?=
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: *
Access-Control-Request-Headers: X-Requested-With, accept, content-type
Date: Tue, 01 Sep 2015 13:05:23 GMT
Content-Length: 0

And still, Firefox blocks the request with the following message :

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:49815//Login/Connect. (Reason: missing token 'access-control-allow-headers' in CORS header 'Access-Control-Allow-Headers' from CORS preflight channel).

Upvotes: 21

Views: 58091

Answers (4)

SendETHToThisAddress
SendETHToThisAddress

Reputation: 3704

I had the same issue but other answers did not work for me, possibly due to working on a newer framework. Here is the official documentation from Microsoft for how to fix the issue as of 2023 https://learn.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-7.0 Below is a shorter explanation.

In the Program.cs file add the following code:

string myAllowSpecificOrigins = "myAllowSpecificOrigins";

builder.Services.AddCors(
    options => {
        options.AddPolicy(
            name: myAllowSpecificOrigins, policy => {
                policy.WithOrigins("https://localhost:44434")
                .AllowAnyHeader()
                .AllowAnyMethod();
            }
        );
    }
);

app.UseCors(myAllowSpecificOrigins);

This will allow the specified port(s) to make a cross-origin request. Be sure to replace the localhost address with the port you're using if it's different. It is also important to get the placement of this code correct in your Program.cs file. UseCors must be placed after UseRouting and before MapControllers (see link for more details and examples with context).

Upvotes: 0

sideshowbarker
sideshowbarker

Reputation: 88066

The problem is, some browsers don’t yet allow the * wildcard for Access-Control-Allow-Headers. Specifically, Firefox 69 and earlier doesn’t. See https://bugzilla.mozilla.org/show_bug.cgi?id=1309358.

So to ensure you get correct behavior in all browsers, the Access-Control-Allow-Headers value you send back should explicitly list all the header names you actually need to access from your frontend code; e.g., in the case in the question: Access-Control-Allow-Headers: Content-Type.

A way you can make that happen without needing to hardcode all the header names is: Have your server-side code take the value of the Access-Control-Request-Headers request header the browser sends, and just echo that into the value of the Access-Control-Allow-Headers response header your server sends back.

Or else use some existing library to CORS-enable your server. Echoing the Access-Control-Request-Headers request-header value into the Access-Control-Allow-Headers response-header value is something most CORS libraries will typically do for you.

Upvotes: 17

nbt45
nbt45

Reputation: 1

I tried in my .net c# mvc app and client app in angular 8 but it is not working. IN web.config, i added

<httpProtocol>
  <customHeaders>
    <clear />
    <add name="Access-Control-Allow-Origin" value="http://localhost:4200" />
    <add name="Access-Control-Allow-Headers" value="Content-Type"/>
  </customHeaders>
</httpProtocol>

In global.axax.cs file also, i added

    void MvcApplication_AuthenticateRequest(object sender, EventArgs e)
    {
        Context.Response.AddHeader("Access-Control-Allow-Origin", "http://localhost:4200");
    }

but it is not working. In chrome in response header it does show as :

Access-Control-Allow-Headers: Content-Type Access-Control-Allow-Origin: http://localhost:4200 Access-Control-Allow-Origin: http://localhost:4200

but in request header it shows as

Access-Control-Request-Headers: access-control-allow-origin,content-type,x-iphoneclientid

whereas it needs to have like

x-iphoneclientid : 8E72FF50-548B

since x-iphoneclientid is the token i validate in my filter class as

    protected override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
    {

        if (request == null || request.RequestUri == null)
        {
            return null;
        }
        // Write your Authentication code here
        IEnumerable<string> monsterApiKeyHeaderValues = null;

        // Checking the Header values
        if (request.Headers.TryGetValues("x-iphoneclientid", out monsterApiKeyHeaderValues))

and above condition does not find so it rejects it and it does not reach to controller.

I even have put following in my controller

[EnableCors("", "", "*")]

can you guide please

Thanks

Upvotes: 0

Yugo Amaryl
Yugo Amaryl

Reputation: 1279

Oftentimes, the threads that I read were suggesting several unecessary configuration steps, which created confusion. It's actually very simple...

For the simple purpose of sending a cross site request, from an angular client, to an ASP controller :

  • No angular interceptors are required.
  • No custom filters on the server side are required.
  • The only mandatory modification is to add this in the server's web.config

    <system.webServer>
          <httpProtocol>
              <customHeaders>
                  <clear />
                  <add name="Access-Control-Allow-Origin" value="*" />
                  <add name="Access-Control-Allow-Headers" value="Content-Type"/>
              </customHeaders>
         </httpProtocol>
    </system.webServer>
    

Upvotes: 30

Related Questions