Search code examples
angularasp.net-corecorssame-origin-policypreflight

ASP.NET Core: Windows Authentication with OPTIONS exception (CORS preflight)


I'm working on a single-page web application. It has ASP.NET Core 3 back end and Angular 9 front end. I run the back end in Visual Studio, on IIS Express, at http://localhost:59280. The front end runs in Visual Studio Code, using ng serve, at http://localhost:4200. Previously I didn't need to turn on CORS in the back-end, because I only tested the app in Chrome, and adding the --disable-web-security command-line argument was enough to turn off the Same Origin Policy. On the live server there is no need for CORS, the above cross-origin situation only occurs on my dev machine.

Now I'd like to debug the frontend in Firefox, but since it's not possible to turn off the Same Origin Policy for Firefox, I have to turn on CORS in the back end. Unfortunately, it doesn't work, because I use Windows Authentication, and it stops the by-default unauthenticated CORS preflight request. This could be solved if I could let HTTP OPTIONS requests be processed without Windows Authentication. I thought this could be done by adding something like this to web.config:

<system.webServer>
  <security>
    <authentication>
      <anonymousAuthentication enabled="true" />
    </authentication>
    <authorization>
      <add accessType="Allow" verbs="OPTIONS" users="*" />
    </authorization>
  </security>
</system.webServer>

...but I got an error message: "This configuration section cannot be used at this path. This happens when the section is locked at a parent level." Apparently web.config is in conflict with launchSettings.json, which seems to control authentication when the back end is run on IIS Express in Visual Studio, using these two lines:

{
  "iisSettings": {
    "windowsAuthentication": true,
    "anonymousAuthentication": false,
    ...

I don't know how I could turn off Windows Authentication separately for HTTP OPTIONS requests, using only launchSettings.json.

Is there a way to turn off Windows Authentication separately for HTTP OPTIONS requests, in an ASP.NET Core 3 application?


Solution

  • 1) The above web.config settings work, I only had to unlock the "anonymousAuthentication" section in applicationhost.config in the .vs directory: <section name="anonymousAuthentication" overrideModeDefault="Allow" />. The value of the "anonymousAuthentication" parameter in launchSettings.json doesn't matter.

    2) Following @MartinStaufcik's suggestion, I added a middleware at the beginning of StartUp.Configure(), which responds to the preflight request (MDN):

    app.Use(async (context, next) => {
      if (context.Request.Method == "OPTIONS") {
        context.Response.StatusCode = 204;
        context.Response.Headers.Add("Access-Control-Allow-Origin", context.Request.Headers["Origin"]);
        context.Response.Headers.Add("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
        context.Response.Headers.Add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
        context.Response.Headers.Add("Access-Control-Allow-Credentials", "true");
        return;
      }
      await next();
    });
    

    3) I also had to add { withCredentials: true } to the arguments of HttpClient.post() in the Angular 9 front end. Without this, the OPTIONS request got 204, but the subsequent POST got 401.