Introduction
Fix To Response to preflight request doesn't pass access control check: The 'Access-Control-Allow-Origin
' header contains multiple values.
Background
In the tip, we would try to explain scenario where a developer might come across a situation trying to login using AngularJs $http
or $resource
, POST
data typically email, password some Token and Web Api. If both the client, server application are hosted in the same domain, then there won't be any potential issue, but that is not the case always.
Often client application might run let's say at http://localhost:53005 and the Web Api might be hosted on http://localhost:52680, in such situations using either $http
or $resource
if data sent to Web API server using POST
method, then the application is likely to throw exception somewhat like below:
"Fix To Response to preflight request doesn't pass access control check:
The 'Access-Control-Allow-Origin' header contains multiple values"
Using the Code
The reason for the above is referred to CORS (Cross Origin Resource Sharing), a detailed analysis on this is also posted in CodeProject here.
Also, there are several tips and tricks available in plural sites for CORS. Check those out here.
There are several ways to address the issue, let's walk through step by step.
- Adding the following
customHeaders
to the web.config of the Web API server.
<httpprotocol>
<customheaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
<add name="Access-Control-Allow-Methods" value="GET,POST,PUT,DELETE,OPTIONS" />
<add name="Access-Control-Allow-Credentials" value="true" />
</customheaders>
</httpprotocol>
After adding the above keys, try running the client application the issue won't be resolved. The error can be seen in Developer Tool > Console Tab of Chrome.
If Internet Explorer 10 or 11 is used, then in Console Tab, the following error can be seen.
XMLHttpRequest: Network Error 0x2efd, Could not complete the operation due to error 00002efd.
- Remove the headers from the web.config mentioned above.
- Search for CORS in Manage Nuget Packages in Visual Studio, I am using VS 2013. Make sure the Online at the left pane is selected and one can see Microsoft ASP.NET Web API 2.2 Cross-Origin Support and install that if not installed. If at all the same package is already installed to your Web API, then a right mark in green rounded circle would be visible against the package.
- At the outset, we have mentioned that while implementing Account Membership, the error is seen. Now to resolve the issue, add the following
using
statement to AccountController
.
The attribute can be applied at specific function level or for all like the following:
[EnableCors(origins: "*", headers: "*", methods: "*")]
The above attribute ideally should be placed just above [Authorize]
attribute.
- In order to apply CORS to all controllers in Web API, one can include the following as the first line in
Register
method in WebApiConfig.cs.
public static void Register(HttpConfiguration config)
{
config.EnableCors();
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
......
Try the Web client and there won't be any error.
- While implementing Individual Authentication using Membership Database, the template in Visual Studio adds ApplicationOAuthProvider.cs file. In the file, there is one method that grants resource credentials. The method name is:
public override async Task GrantResourceOwnerCredentials
(OAuthGrantResourceOwnerCredentialsContext context)
In that method, one needs to check if some what like this is ever added.
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin",
new[] { "yourdomain:yourpostnumber" });
If that is there and the client tries to login, then the following error can be seen in Console tab.
No 'Access-Control-Allow-Origin
' header is present on the requested resource. Origin 'http://localhost:53005
' is therefore not allowed access. The response had HTTP status code 500.
This is because we have already enabled config.EnableCors();
in WebApiConfig.cs and also try to add context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "yourdomain:yourpostnumber" });
So make sure to take off the context.OwinContext.Response.Headers.Add
line from ApplicationOAuthProvider.cs file and give a try. No error would be visible.
Hope the tip helps in resolving the issue.