Access-Control-Allow-Origin not allowing HTTP GET from a remote server - ajax

I'm using Ajax to download XML using HTTP GET getting following error:
XMLHttpRequest cannot load https://remoteserverfqdn:8444/cuic/permalink/PermalinkViewer.htmx?viewId=F52A08751000014B3835F5E80AB43E68&linkType=xmlType&viewType=Grid. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access. The response had HTTP status code 403.
The code I'm using to get data:
$(document).ready(function()
{
$.ajax({
type: "GET",
url: "https://remoteserverfqdn:8444/cuic/permalink/PermalinkViewer.htmx?viewId=F52A08751000014B3835F5E80AB43E68&linkType=xmlType&viewType=Grid",
dataType: "xml",
success: parseXml
});
});
Remote server is a blackbox so there's nothing I can do on that side to enable Access-Control-Allow-Origin. I tried installing ARR and URL Rewrite on IIS to act as a reverse proxy. That works fine when accessing the page directly in a browser, but when using Ajax and HTTP GET it gives me the same error.
Does anyone know a different method I could use to download the xml bypassing CORS? I did read up on JSONP but I think a change on the server side (the blackbox one) is needed for that to work?
If ARR and URL rewrite is the correct way to go for this, does anyone know if there is a setting available there I'm missing to set the Origin HTTP header to the remote server url.

Related

Chrome allows ajax going to http foreign origin where firefox does not - why?

I have a JSP with javascript code, running on a server with HTTPS. In this JavaScript I trigger a request to another (local) webserver like this:
let url = 'http:/localhost:3111/doSomePost';
$.ajax({
type: 'POST',
url: url,
contentType: 'application/octet-stream',
processData: false,
data: uint8array
})
This requires CrossOrigin to be enabled on the local webserver in order to work - I configured that part and it works.
But it only works in Chrome. Not in Firefox.
Firefox will give me this error:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading
the remote resource at
http://localhost:3111/doSomePost. (Reason: CORS
request did not succeed).
I can see in the network tab of firefox devtools, that firefox does not even bother to send the preflight request (the OPTIONS request). So Firefox just decides it won't send that request (and I suspect it to be because that local webserver protocol is HTTP).
I have now changed my local webserver to use HTTPS using a self-signed certificate as described here: https://www.baeldung.com/spring-boot-https-self-signed-certificate
Now, it works in Firefox and Chrome (after I manually add the certificate which is not valid).
I just wonder why chrome has no problem but firefox does.
UPDATE: corrected minor typo in error message
I've managed to find a better solution. Instead of switching the local webserver to HTTPS in order to get firefox working, I changed the above request to:
let url = 'http:/localhost:3111/doSomePost';
$.ajax({
type: 'POST',
url: url,
data: jsonWithBase64encodedData
})
This now qualifies as so called "Simple request" (https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) again, and is being treated in a similar, and most importantly, working way in all browsers.

identity Server - Configuring CORS for bearer options

I am testing the jquery ajax calls to the API server from a different domain. Unfortunately I am getting an OPTIONS error. Here is my request code:
$.ajax({
url: "https://localhost:44356/api/Default/",
headers: {
"Authorization": "Bearer " + user.access_token
},
success: function (res) {
logAjaxResult(res);
},
error: function() {
logAjaxResult('Error');
}
}))
Which gives
XMLHttpRequest cannot load https://localhost:44356/api/Default/. Response for preflight has invalid HTTP status code 405.
Normally this is an easy fix - I install Microsoft.AspNet.WebApi.Cors, set up a provider and allow OPTIONS through always. I can see how I would normally do this on the Identity Server box too as there is a CorsProvider you can register up. My issue however is on the API box I am using IdentityServerBearerTokenAuthenticationOptions and I see no CORs options. When I try to set up the WebAPI.cors provider though I get an error saying there are multiple origins set on the server to allow. This indicates to me (correct me if I'm wrong) that the WebApi box has somehow got the CORs settings from my identity server box that is registered as it's authority. Is this right?
How do I configure to allow pre-flight requests with app.UseIdentityServerBearerTokenAuthentication(options)?
Many thanks
This issue was resolved when I found the documentation uses
Microsoft.Owin.Cors
I was using the package
Microsoft.AspNet.WebApi.Cors

Ajax cross domain request allowed in internet explorer

I've been asked to create a feedback page that can be requested from another site.
I'm using progressive enhancement to display the page.
The ajax request for when I am able to use a jquery dialog is as follows
jQuery.support.cors = true;
$.ajax({
type: 'get',
crossDomain: true,
url: this.href
}).done(function (data) {
$dialogFeedback.html(data);
}).error(function (jqXHR, textStatus, errorThrown) {
$dialogFeedback.html(jqXHR.responseText || textStatus);
});
During testing I have noticed Internet explorer seems to be allowing a cross domain call even when the response Access-Control-Allow-Origin HttpHeader is not set to be the client domain. I've noticed the Http origin header is always null.
Chrome and Firefox respect it. The Http origin header is not null.
The client site making the call is on a different port to the feedback site but both are localhost. I have read that a different port number is considered cross domain.
At the moment I find myself having to retrieve the caller/client domain from the Referrer Http header and returning a 404 if the domain is not known by us.
Really I was hoping to rely on the Access-Control-Allow-Origin HttpHeader!
. . . so my question is why is this happening? Is it actually expected/probable? What is the best solution?
Thanks
If the origin header is missing, then the request is not cross-domain according to IE. IE violates the same-origin policy RFC in several ways. First, it ignores port numbers. Second, IE will allow domains that are in the trusted zone to interact without applying the same origin policy

Access to restricted URI denied" code: "1012

On domain A (localhost:8080) I run this code to access an unauthenticating REST serivce on domain B (localhost):
req = new XMLHttpRequest();
req.open('GET', 'http://localhost/rest/service');
req.send();
This works fine and I do get my response across domains as I have Apache on domain B set the response header:
Header set Access-Control-Allow-Origin "http://localhost:8080"
However if I now turn on authentication for the REST service and try to run the same request:
req.open('GET', 'http://admin:admin#localhost/rest/service');
It now produces this error in Firebug:
Access to restricted URI denied" code: "1012
I'm confused that I am able to sucessfully make cross domain ajax calls to the authenticated service bypassing the same origin policy, yet when authentication is required on the service Firefox decides not to allow the ajax call? How can I fix this without using jsonp etc, as the production server won't be able to provide PHP or Servlet hosting.
It's easy with JQuery 1.5+, which I recommend you use for your JavaScript solution:
$.ajax({
url: 'http://admin:admin#localhost/rest/service',
crossDomain:true, // Here is the JSONP callback logic
success: function(data){
console.log(data); // data is what comes back from your remote file
}
});

handling a redirect from a cross-origin post in AJAX

We are trying to create a RESTful API that will be hosted on server x.foo.com. Client html applications (built in jquery) will be hosted on y.foo.com.
I am dealing with cross-domain issues by setting the Access-Control-Allow-Origin header as described here http://www.w3.org/TR/cors/.
So far so good, and I can now successfully make AJAX calls from host y to host x.
However, I ran into a gotcha with POST requests. The typical response to a post request is a redirect. However, the XMLHttpRequest object will not follow cross domain redirects, thus resulting in a failed call.
// Hosted on y.foo.com
$.ajax({
type: "POST",
url : http://x.foo.com/myapp/",
success: function(data) {
alert("success!");
}
});
// Return status: 302
// (Which errors out in firebug)
Anyone know of any techniques to handle the redirect (to a resource on server x) that I get from this post for a client hosted on y?
How about the client sends a special header for AJAX requests, and depending on whether it's an AJAX request or not, you can change the response instead of doing a redirect.

Resources