Asp.net core web api using windows authentication - Cors request unauthorised

1) Set Allow Windows, and anonymous Authentication flag to true in launchSettings.json file (Development settings file).

Anonymous Authentication: is needed to allow Pre flight option request.

{
  "iisSettings": {
    "windowsAuthentication": true,
    "anonymousAuthentication": true,
    "iis": 
      ...
}

2) Add Cors Policy in Configure service method.

public void ConfigureServices(IServiceCollection services)
{
         
        ...
          services.AddCors(options =>
              {
                  options.AddPolicy("MyCustomCorsPolicyName",
                              builder => builder.WithOrigins("http://YourDomainName/")
                                      .AllowAnyMethod()
                                      .AllowAnyHeader()
                                      .AllowCredentials()
                              );
              });
          services.AddAuthentication(IISDefaults.AuthenticationScheme);
          services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);      
}
   

3: Adds a CORS middleware to your web application pipeline to allow cross domain requests.

public void Configure(IApplicationBuilder app)
{
   ....
   app.UseCors("MyCustomCorsPolicyName");
   app.UseMvc();
}

4) Add Authorize Attribute on top of your controller to Force, client to send credentials

[Authorize]
public class MyAPIController : ControllerBase
{
...
}

5) In JQuery or any client that you are using set withCredentials property flag to true

$.ajax({
                type: "POST",
                datatype: "json",  
                url: "YourApiUrl",              
                xhrFields: {
                    withCredentials: true
                }

This worked for me in my development environment using .net core 2.2, IIS Express with Windows Authentication.


You may want to read this thread: https://github.com/aspnet/CORS/issues/60. You can mix anonymous and NTLM so that your CORS preflights aren't denied (since they don't include windows credentials). IIS handles NTLM authentication before it even gets to the middleware so this is probably an IIS thing. You may need to allow anonymous CORs preflight checks.


Using IIS CORS Module solved the problem superbly. Below URL is for reference.

Working with Windows Authentication While this is by no means the only scenario solved by the CORS module, it was important enough to warrant calling out. Previously, if you tried to make a cross-domain request to an application that used Windows Authentication, your preflight request would fail since the browser did not send credentials with the preflight request. There was no way to work around this without enabling anonymous authentication in your application. Since the CORS module kicks in before authentication, it makes it possible to handle a pre-flight request without compromising on the security model of your application. Here's an example of what your web.config might look like.

https://blogs.iis.net/iisteam/getting-started-with-the-iis-cors-module

Sample Code:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <!-- To customize the asp.net core module uncomment and edit the following section. 
         For more info see https://go.microsoft.com/fwlink/?linkid=838655 -->
         <system.web>
        <authentication mode="Windows"/>
    </system.web>
  <system.webServer>
  <cors enabled="true" failUnlistedOrigins="true">
            <add origin="http://localhost:60096" allowCredentials="true" >
            <allowHeaders allowAllRequestedHeaders="true">
                    <add header="Header1" />
                </allowHeaders>
            </add>
        </cors>
    <handlers>
      <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
    </handlers>
    <aspNetCore processPath="dotnet" arguments=".\Project.Api.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" />
  </system.webServer>
</configuration>