WebAPI CORS with Windows Authentication - allow Anonymous OPTIONS request WebAPI CORS with Windows Authentication - allow Anonymous OPTIONS request angularjs angularjs

WebAPI CORS with Windows Authentication - allow Anonymous OPTIONS request


I used self-hosting with HttpListener and following solution worked for me:

  1. I allow anonymous OPTIONS requests
  2. Enable CORS with SupportsCredentials set true
var cors = new EnableCorsAttribute("*", "*", "*");cors.SupportsCredentials = true;config.EnableCors(cors);var listener = appBuilder.Properties["System.Net.HttpListener"] as HttpListener;if (listener != null){    listener.AuthenticationSchemeSelectorDelegate = (request) => {    if (String.Compare(request.HttpMethod, "OPTIONS", true) == 0)    {        return AuthenticationSchemes.Anonymous;    }    else    {        return AuthenticationSchemes.IntegratedWindowsAuthentication;    }};}


I have struggled for a while to make CORS requests work within the following constraints (very similar to those of the OP's):

  • Windows Authentication for all users
  • No Anonymous authentication allowed
  • Works with IE11 which, in some cases, does not send CORS preflight requests (or at least do not reach global.asax BeginRequest as OPTIONS request)

My final configuration is the following:

web.config - allow unauthenticated (anonymous) preflight requests (OPTIONS)

<system.web>    <authentication mode="Windows" />    <authorization>        <allow verbs="OPTIONS" users="*"/>        <deny users="?" />    </authorization></system.web>

global.asax.cs - properly reply with headers that allow caller from another domain to receive data

protected void Application_AuthenticateRequest(object sender, EventArgs e){    if (Context.Request.HttpMethod == "OPTIONS")    {        if (Context.Request.Headers["Origin"] != null)            Context.Response.AddHeader("Access-Control-Allow-Origin", Context.Request.Headers["Origin"]);        Context.Response.AddHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, MaxDataServiceVersion");        Context.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");        Context.Response.AddHeader("Access-Control-Allow-Credentials", "true");        Response.End();    }}

CORS enabling

public static class WebApiConfig{    public static void Register(HttpConfiguration config)    {        // all requests are enabled in this example. SupportsCredentials must be here to allow authenticated requests                  var corsAttr = new EnableCorsAttribute("*", "*", "*") { SupportsCredentials = true };        config.EnableCors(corsAttr);    }}protected void Application_Start(){    GlobalConfiguration.Configure(WebApiConfig.Register);}


This is a much simpler solution -- a few lines of code to allow all "OPTIONS" requests to effectively impersonate the app pool account. You can keep Anonymous turned Off, and configure CORS policies per normal practices, but then add the following to your global.asax.cs:

            protected void Application_AuthenticateRequest(object sender, EventArgs e)            {                if (Context.Request.HttpMethod == "OPTIONS" && Context.User == null)                {                    Context.User = System.Security.Principal.WindowsPrincipal.Current;                }            }