Home » Angularjs » Web Api 2 Preflight CORS request for Bearer Token

Web Api 2 Preflight CORS request for Bearer Token

Posted by: admin November 29, 2017 Leave a comment

Questions:

I have a web-app with an AngularJS front-end and a Web Api 2 back-end, and it uses bearer-tokens for authentication.

All is well in FireFox & IE, but with Chrome, my initial login request is SOMETIMES pre-flighted.

Here’s the call from the AngularJS service:

$http.post(http://localhost:55483/token, data, { headers: { ‘Content-Type’: ‘application/x-www-form-urlencoded’ } }).success(function (response) { … });

The preflight request gets kicked back with an “Allow-Access-Control-Origin” error.

However, if I click the Login button again (thereby re-sending the above request) all is well.

Any idea on how to prevent/trap/handle this?

PS: I use the LOC

context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });

in the ApplicationOAuthProvider.cs file to put the CORS allow-header on the /Token request, which works fine in IE, FireFox and sometimes in Chrome.

Answers:

The below is Fancy comment:

Figured this out with help from post by LeftyX on Jun 29:
– Move
this LOC app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll); to the
FIRST LINE in the ConfigureAuth method of Startup.Auth.cs.
– Then,
REMOVE this LOC
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin",
new[] { "*" });
from the GrantResourceOwnerCredentials() method of
ApplicationOAuthProvide.cs.

Preflight CORS-request them gets
handled properly, and then the actual requet goes through

Thank man, you save my whole day.
Cause it happens for many guys, I bring your comment to answer box for other guys can see it.

I don’t want to get vote up for this. Please comment on my answer instead

Thank you

Questions:
Answers:

I hope this is able to help somebody out there. For me:

  • adding the app.useCors(); LOC did not work.
  • Adding the app.useCors(); LOC worked for other people on my team.

So I needed a solution that would work across everyone’s environments.

Ultimately what I ended up doing was adding the header and value right into the Web.config with the following (where localhost:9000 is my node application that is serving up angular):

<system.webServer>
    <httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Origin" value="http://localhost:9000" />
        <add name="Access-Control-Allow-Headers" value="Content-Type"/>
      </customHeaders>
    </httpProtocol>
  </system.webServer>

Then in production you can just change the origin value to the production front-end url.

If you want CORS enabled for all origins, change the value to "*".

Questions:
Answers:

By default – Access-Control-Max-Age: seconds is 0 and your requests not caching.

Try set it to max value: (Owin selfhost). It solve problem with extra OPTIONS requests

            app.UseCors(new CorsOptions
            {
                PolicyProvider = new CorsPolicyProvider
                {
                    PolicyResolver = context => Task.FromResult(new CorsPolicy
                    {
                        AllowAnyHeader = true,
                        AllowAnyMethod = true,
                        AllowAnyOrigin = true,
                        SupportsCredentials = false,
                        PreflightMaxAge = Int32.MaxValue // << ---- THIS
                    })
                }
            });