Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CORS + Windows Authentication not playing nice with Edge or IE

I've having a CORS issue that only happens in Edge and IE11. Chrome works fine.

My setup is an ASP.NET MVC5 app (client) that has a script calling out to a separate ASP.NET MVC5 app (API) that only contains WebAPI controllers. Security in both apps is through Windows Authentication.

Currently, everything is running on localhost during development.

When the client script makes the call to the API, the OPTIONS preflight works fine. However, when the GET happens, Edge and IE get the following error:

enter image description here

In this image, localhost:50281 is the client, and localhost:47205 is the API.

Something that is weird, is that the call isn't actually hitting the controller. The controller is decorated with a custom AuthorizeAttribute, and a breakpoint in there doesn't ever get hit.

Here is how CORS is set up in the API project:

Global.asax.cs

protected void Application_BeginRequest()
{
    if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
    {
        Response.Headers.Add("Access-Control-Allow-Origin", "http://localhost:50281");
        // Yes, there are too many headers. I've been working on this a while, and there are a few overkill options that have crept in
        Response.Headers.Add("Access-Control-Allow-Headers", "X-AspNet-Version,X-Powered-By,Date,Server,Accept,Accept-Encoding,Accept-Language,Cache-Control,Connection,Content-Length,Content-Type,Host,Origin,Pragma,Referer,User-Agent");
        Response.Headers.Add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, HEAD, OPTIONS");
        Response.Headers.Add("Access-Control-Allow-Credentials", "true");
        Response.Headers.Add("Access-Control-Max-Age", "600");
        Response.End();
    }
}

WebApiConfig.cs

public static void Register(HttpConfiguration config)
{
    // Web API configuration and services
    var cors = new EnableCorsAttribute("http://localhost:50281", "*", "*");
    cors.SupportsCredentials = true;
    cors.PreflightMaxAge = 600;
    config.EnableCors(cors);
    // Web API routes
    config.MapHttpAttributeRoutes();

    config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{id}",
        defaults: new { id = RouteParameter.Optional }
    );
}

Here is the script function in the client project:

GetStatus = () => {
    $.ajax({
        type: "GET",
        url: apiUrl,
        dataType: "json",
        crossDomain: true,
        xhrFields: {
            withCredentials: true
        },
        contentType: "application/json; charset=UTF-8",
        success: (result) => {
            this.Status(result);
        }
    });
}

Update

I modified Global.asax.cs to ensure that the Access-Control-Allow-Origin and Access-Control-Allow-Credentials are included with every request, as was suggested. However, this still results in a 401 only in Edge and IE. It works fine in Chrome.

Update 2

I guess something did change. I missed that the error is now reduced to the following: enter image description here

This is obviously from me getting the appropriate headers in place. However, for some reason, Edge and IE are still not letting the authentication pass through, despite the presence of withCredentials: true. Is there another piece I'm missing?

like image 838
Devin Goble Avatar asked Jan 25 '18 20:01

Devin Goble


1 Answers

ASP.NET (OWIN)

Install-Package Microsoft.Owin.Cors

Startup.cs:

app.UseCors(CorsOptions.AllowAll)

Web Config:

<system.webServer>
  <handlers>
    <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
    <remove name="OPTIONSVerbHandler" />
    <remove name="TRACEVerbHandler" />
    <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
  </handlers>
</system.webServer>
like image 94
anıl yıldırım Avatar answered Sep 18 '22 13:09

anıl yıldırım