ASP.net same origin policy header not working

I get an error message:

XMLHttpRequest cannot load http://www.scirra.com/handlers/arcadeProcessScore.ashx. Origin http://static1.scirra.net is not allowed by Access-Control-Allow-Origin. 

In arcadeProcessScore.ashx , I have the lines:

 public void ProcessRequest (HttpContext context) { context.Response.AppendHeader("Access-Control-Allow-Origin", "http://static1.scirra.net"); context.Response.AppendHeader("Access-Control-Allow-Origin", "https://static1.scirra.net"); context.Response.ContentType = "text/plain"; 

However, the error still persists.

I also tried simply:

 context.Response.AppendHeader("Access-Control-Allow-Origin", "*"); 

This does not work either.

If I add <add name="Access-Control-Allow-Origin" value="*"/> at the web.config level, it works, but obviously is not a solution.

How can I let arcadeProcessScore.ashx accept requests from static1.scirra.net ? Thanks for any help.

+4
source share
3 answers

I did my own testing myself, using XmlHttpRequest to access the handler in my project. The setup I used was to publish the application on my local IIS (this is version 6.1, so there may be differences in behavior up to 7.5) and so that the Default.aspx page Default.aspx my handler, which runs on the development server in Visual Studio. Like this:

 http://mymachine/WebTest/Default.aspx -> XmlHttpRequest get request to http://localhost:58025/WebTest/TestHandler.ashx 

Code in the handler:

 public void ProcessRequest (HttpContext context) { context.Response.AppendHeader("Access-Control-Allow-Origin", "http://mymachine"); context.Response.Cache.SetCacheability(HttpCacheability.NoCache); context.Response.ContentType = "text/plain"; context.Response.Write("Hello World " + DateTime.Now.ToString()); } 

Using IE9, the behavior was the same regardless of whether I sent the Access-Control-Allow-Origin header from the handler or not. IE9 gives a warning, asking the user to confirm the loading of the content.

Both Chrome (version 21.0.1180.79 m) and FF (version 14.0.1) actually generate requests to the handler and respect the header sent by the handler.

So this worked with Chrome and FF:

 context.Response.AppendHeader("Access-Control-Allow-Origin", "http://mymachine"); 

It happened:

 context.Response.AppendHeader("Access-Control-Allow-Origin", "*"); 

But I couldn’t get any of them to show the content if I try to add several different allowed sources to the same answer. For me, none of them worked:

  • Add multiple response headers

     context.Response.AppendHeader("Access-Control-Allow-Origin", "http://mymachine"); context.Response.AppendHeader("Access-Control-Allow-Origin", "http://someothermachine"); 
  • Add one title, two sources separated by commas

     context.Response.AppendHeader("Access-Control-Allow-Origin", "http://mymachine, http://someothermachine"); 
  • Add one title, separation of two sources

     context.Response.AppendHeader("Access-Control-Allow-Origin", "http://mymachine http://someothermachine"); 
  • Add one title, separation of two sources

     context.Response.AppendHeader("Access-Control-Allow-Origin", "http://mymachine; http://someothermachine"); 

To make it work, I had to follow the recommendations given in this answer . Then my handler looks like this:

 public void ProcessRequest(HttpContext context) { string[] allowedOrigins = new string[] { "http://mymachine", "http://someothermachine" }; string origin = context.Request.Headers.Get("Origin"); if (allowedOrigins.Contains(origin)) context.Response.AppendHeader("Access-Control-Allow-Origin", origin); context.Response.Cache.SetCacheability(HttpCacheability.NoCache); context.Response.ContentType = "text/plain"; context.Response.Write("Hello World " + DateTime.Now.ToString()); } 

In this case, both Chrome and FF accept the output of the handler from both sources.

+5
source

The problem with your code is that the Cross Origin response header is sent to the browser with the actual request, whereas it should be up to the actual request made!

W3 recommends that the user agent implement the request before sending the Cross-Origin HTTP request, which means that either the response to the page containing the actual request or the response to a simple request known as a preflight request (which is done before the actual request) must contain a Cross Header response to the source text when the actual request is executed.

Cross Origin headers returned from the pre-validation request are stored in the result cache before the flight. When the Cross-Origin HTTP request is executed, the user agent checks the Access-Control-Allow-Origin header in the result cache before the flight, and if it does not exist, an exception is thrown:

the address cannot be loaded, the source address is not resolved using Access-Control-Allow-Origin.

When you put the Access-Control-Allow-Origin header in web.config , any response returned from the server contains the Access-Control-Allow-Origin header, and the browser Sends the actual cross-domain request.

It is best to make a simple ajax call (pre-sale request) before you call the actual cross-domain request and send all the response headers needed with the pre-flight check request.

+3
source

Can you wrap the web.config element in a location tag so that it runs only for your ashx location, and not somewhere else - this will mitigate the “obviously not answer” problem?

 <location path="~/path/to/handler/arcadeProcessScore.ashx"> <httpProtocol> <customHeaders> <clear /> <add name="Access-Control-Allow-Origin" value="http://static1.scirra.net" /> </customHeaders> </httpProtocol> </location> 
+1
source

All Articles