CORS + Windows Authentication Doesn't Play Well with Edge or IE

I have a problem with CORS that only occurs in Edge and IE11. Chrome is working fine.

My setup is an ASP.NET MVC5 application (client) that has a script that calls a separate ASP.NET MVC5 application (API) that contains only WebAPI controllers. Security in both applications is through Windows authentication.

Everything currently works on localhost during development.

When the client script makes an API call, the OPTIONS preview works fine. However, when a GET occurs, Edge and IE receive the following error:

enter image description here

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

Something strange is that the call does not actually push the controller. The controller is decorated with a custom AuthorizeAttribute , and the breakpoint never gets there.

Here's how CORS is configured 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 project 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 Access-Control-Allow-Origin and Access-Control-Allow-Credentials are included in every request as suggested. However, this still leads to 401 only in Edge and IE. It works fine in Chrome.

Update 2

I think something has changed. I skipped that the error now boils down to the following: enter image description here

It is obvious that I am getting the appropriate headers. However, for some reason, Edge and IE still do not allow authentication, despite having withCredentials: true . Is there another piece that I am missing?

+5
source share
2 answers

ASP.NET (OWIN)

 Install-Package Microsoft.Owin.Cors 

Startup.cs:

 app.UseCors(CorsOptions.AllowAll) 

Web configuration:

 <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> 
+2
source

You need to return the Access-Control-Allow-Origin (ACAO) and Access-Control-Allow-Credentials (ACAC) headers with a GET request as well as a request for OPTIONS options. These two headers should be returned for each cross-domain request where you send cookies / authentication.

The best / easiest / cleanest method is that for ALL requests (OPTIONS, GET, POST, etc.) that include the Origin request header, add the ACAO and ACAC headers. Then for OPTIONS queries also add other Access-Control-Allow- * headers ...

Also, FWIW, it is a reasonable idea to return the value of the Origin request header to the ACAO header, rather than hardcode as http://localhost:50281 . Thus, if you change your port or something else, it will still function.

0
source

Source: https://habr.com/ru/post/1274956/


All Articles