I am seeing 401 responses when making a CORS request via jQuery AJAX from iOS Safari/Chrome or Windows 7 Firefox clients but not when made from IE/Chrome Windows 7 Clients.
I have a ASP.NET MVC 5 application which calls a Web Api 2.2 service hosted on an IIS 8.5 sever in my enterprise domain with URLs such as
mvc.mydom.com
api.mydom.com
Both sites are setup to require windows authentication.
The MVC application makes requests to the API service using a jQuery Ajax command like so
$.ajax({
dataType: "json",
url: http:'//api.mydom.com/Cars/1',
beforeSend: function (xhr) {
xhr.withCredentials = true;
},
xhrFields: {
withCredentials: true
},
success: function (data) {
//Do stuff
});
},
error: function (xhr, ajaxOptions, thrownError) {
//alert stuff
}
});
In my Web API Application I enable CORS support as follows:
// configured by application start
config.EnableCors();
config.SetCorsPolicyProviderFactory(new CorsPolicyFactory());
public class CorsPolicyFactory : ICorsPolicyProviderFactory
{
ICorsPolicyProvider provider = new MisCorsPolicyProvider();
public ICorsPolicyProvider GetCorsPolicyProvider(System.Net.Http.HttpRequestMessage request)
{
return this.provider;
}
}
public class MisCorsPolicyProvider : ICorsPolicyProvider
{
private CorsPolicy policy;
public MisCorsPolicyProvider()
{
this.policy = new CorsPolicy
{
AllowAnyMethod = true,
AllowAnyHeader = true,
SupportsCredentials = true
};
this.policy.Origins.Add("http://mvc.mydom.com");
}
public Task<CorsPolicy> GetCorsPolicyAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
return Task.FromResult(this.policy);
}
}
Wondering if it was an issue with the preflight request I came across a couple of references which suggested that IIS 8.5 required the following change to the Web Config.
replace
<system.webServer>
<handlers>
<remove name="OPTIONSVerbHandler"/>
</handlers>
<system.webServer>
with
<system.webServer>
<handlers>
<remove name="OPTIONS"/>
</handlers>
<system.webServer>
which didn't help anything.
Looking at the requests in the developer tools both on iOS and Firefox Windows I don't see the credential being passed but I do in windows IE/Chrome.
Examples of the bad header/response are as follows:
GET http://api.mydom.com/Cars/1 HTTP/1.1
Host: api.mydom.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:29.0) Gecko/20100101 Firefox/29.0
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: en-gb,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://mvc.mydom.com/Home/Index
Origin: http://mvc.mydom.com
Connection: keep-alive
RESPONSE
HTTP/1.1 401 Unauthorized
Content-Type: text/html
Server: Microsoft-IIS/8.5
WWW-Authenticate: Negotiate
X-Powered-By: ASP.NET
Date: Wed, 17 Sep 2014 14:25:49 GMT
Content-Length: 1293
Proxy-Support: Session-Based-Authentication
On windows IE/Chrome network profiling I see a 401 error quickly followed by 200 response to the desired resource(s). This doesn't happen on iOS or win Firefox leading me to believe it's might be something to do with preflight request failing however the requests are GET's not OPTIONS. I assumed preflight requests are OPTIONS
Struggling to see what I am missing any ideas?
UPDATE
Ok I think it might because Firefox and I presume Safari and iOS correctly implement the W3C specification which states that preflight requests should not pass user credentials; as IIS is set up to require windows authentication the request fails with a 401.2 error. IE, chrome seem to carry on and authenticate hence the success. So I suppose is there a way I can turn off windows authentication for OPTIONS requests only?