I have this webapp where I make a post request using Ajax from Domain A to a rest service on Domain B
Domain B has been set up to serve the response with the CORS Access-Control* headers in order to get the cross-domain posting to work
Headers in response from domain B:
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: content-type
Access-Control-Allow-Methods: POST GET OPTIONS
Access-Control-Allow-Origin: https://sub.domain-a.com
Access-Control-Max-Age: 180
The Ajax code
$.ajax({
url: 'https://sub.domain-b.com',
type: 'POST',
contentType: 'application/json',
headers: {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'
},
data: json,
dataType: 'json',
xhrFields: {
withCredentials: true
},
success: function (data) {
},
error: function (jqXHR, textStatus, errorThrown) {
}
});
I am logged in on both domains and my request sends the necessary cookie (withCredentials=true), but I am still getting a 403 Forbidden from the response
Both domains are using SSL a certificate
I am beginning to wonder if the SSL's are causing the problem as this worked before and I am getting nothing in my logs
Are there anyone here that have any experience with something similar?
Any pointers?
It could be something similar to this issue:
Pre-flight OPTIONS request failing over HTTPS
Typically when the issue is with SSL and the preflight request though you wouldn't get back a 403, you'd just get the OPTIONS request aborting.
How does the service authenticate and authorise? Are you using self-signed certificates? It sounds like you're correct in thinking that SSL is causing the issue and without more info it's hard to say what your specific problem is.
Related
I'm calling facebook graph api using ajax as follows,
$.ajax({
url: "https://graph.facebook.com/oauth/access_token?client_id=CLIENT_ID&client_secret=CLIENT_SECRET&grant_type=fb_exchange_token&fb_exchange_token="+accessToken,
type: 'GET',
contentType: "application/json",
success: function (response) {
},
error: function (error) {
console.log('Error occurd while retrieving long live access token');
}
});
But it shows error as follows,
Request header field authorization is not allowed by Access-Control-Allow-Headers in preflight response.
If I make the request using postman or using the browser it works fine. Appriciate any help to resolve this issue. I tried several answers regarding the Access-Control-Allow-Headers in the server side, but in this case I don't have the control over facebook side.
In my website, something weird is happening while running in Internet Explorer. My website and API are hosted separately. API is having anonymous authentication with token based authorization. MVC website is having windows authentication. Most of the times everything works as expected. But sometimes what happens is while calling the API from javascript my Authorization is headed changed to NTLM instead of Bearer. I am giving some screenshots of the same scenario.
Successful API Call:
401 Unauthorized Call:
My Ajax is as follows:
$.ajax({
url: src,
type: 'GET',
cache: false,
async: true,
data: (parameters),
headers: {
'Authorization': 'Bearer ' + sessionStorage.getItem('token')
},
contentType: 'application/json'
dataType: 'json',
success: successCallback,
error: function (xhr, textStatus, errorThrown) {
ErrorPopup("error occur");
}
,
beforeSend: function (xhr, settings) { xhr.setRequestHeader('Authorization', 'Bearer ' + sessionStorage.getItem('token')); }
});
I have debugged all API calls and always authorization header is set to Bearer ... still, somehow some way NTLM is taking control of it and making my API calls unauthorized. Please share some insights how could I solve this. I cannot change authentication in IIS as it's beyond my control. If you need any more inputs I can provide that too.
It looks like there is a redundancy in your authorization headers (headers array + beforeSend). Remove one of them and test (reason : RFC 2616 says that several headers with the same name should be concatenated on the same line, and maybe the server is replying with an NTLM authorization request to such a request that it doesn't allow).
Here is a problem: when user make authorisation on one server (e.g. a.com) he should be authorised (over jQuery-ajax) on another server (e.g. b.com) - the user-DB is shared for both this sites. Js-code written is
var form = jQuery('#auth_form');
var data = form.serialize();
var url = 'http://www.b.com/auth';
jQuery.ajax({
url: url,
crossDomain: true,
type: 'POST',
dataType: 'html',
data: data,
xhrFields: {
withCredentials: true
},
success: function (html) {
},
error: function (jqXHR, textStatus) {
}
});
When server send response, he set some of header
header("Access-Control-Allow-Origin: http://www.a.com");
header("Access-Control-Allow-Credentials: true");
header("Access-Control-Allow-Methods: POST,GET,OPTION");
header("Access-Control-Max-Age: 1000");
header("Access-Control-Allow-Headers: x-requested-with, Content-Type, origin, authorization, accept, client-security-token");
It works fine in Chrome and Opera, but ForeFox seems even dousn't send request to server and writes something like this in console log:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://www.b.com. This can be fixed by moving the resource to the same domain or enabling CORS.
FireFox is latest version (37.0.1) and it's written that version 3.5+ supports CORS and i don't understand what is going wrong? I've tried look network through Fiddler - and i don't see request to b.com from FireFox (from Chrome i see one - everything is Ok). I've tried manage FireFox options (capability.policy.default.XMLHttpRequest.open = allAccess), but it doesn't work. Where is any solution? Any help will be appreciated.
I am sending cross domain ajax request, the response comes back with status 200. I also see that the request arrives to the server.
I have this in my server:
context.Response.Headers.Add("Access-Control-Allow-Origin", "*");
context.Response.Headers.Add("Access-Control-Allow-Credentials", "true");
context.Response.Headers.Add("Access-Control-Allow-Methods", "GET, POST, DELETE, OPTIONS");
context.Response.Headers.Add("Access-Control-Allow-Headers", "*");
This is on the client:
$.ajax({
type: "POST",
url: this.SERVER + url,
data: data,
xhrFields: {
withCredentials: true
},
success: function (a, b) {
debugger;
alert("sdsd");
},error : function(a,b) {
debugger;
},
dataType: 'json'
});
this is the request from the chrome browser
In firefox its I get the error:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:2000/PageHandler.ashx. This can be fixed by moving the resource to the same domain or enabling CORS
My wild guess is that since you are sending the Access-Control-Allow-Credentials header you cannot put * in Access-Control-Allow-Origin. Try specifying the origin as that of your JavaScript client.
I am basing this on the following piece of information from the Mozilla Developer Networks Documentation on CORS:
The origin parameter specifies a URI that may access the resource.
The browser must enforce this. For requests without credentials, the
server may specify "*" as a wildcard, thereby allowing any origin to
access the resource.
I'm working with CodeIgniter2 Rest API and AJAX to make requests from a smartphone with PhoneGap to a AWS server with apache.
Everything was working fine when working on my localhost/browser.
But when trying to set up a distant server things got bad.
I have configured my server properly with CORS so that it allows external requests as explained here :
http://dev.nuclearrooster.com/2011/01/03/cors-with-apache-mod_headers-and-htaccess/
To secure the API, I have been setting up an API KEY that I have to pass in the header of my request like so:
$.ajax({
type:"GET",
url: server_url + 'user/available',
headers: { 'X-API-KEY': key },
dataType: 'json'
});
But then, after seeing my ajax called being refused because of an invalid API Key, I have been trying to make sure the server received the key. and it doesnt. when I try to echo my key, its empty.
I can see in my debug console the following:
Request header field X-API-KEY is not allowed by Access-Control-Allow-Headers.
So I have been modifying my .htaccess following this post:
Header add Access-Control-Allow-Origin "*"
Header add Access-Control-Allow-Headers "origin, x-requested-with, content-type, x-api-key"
Header add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"
so now, the message is gone but the problem still remains the same ... why ?
How can I transmit this X-API-KEY through my AJAX call Header so I can authentificate my users ?
Many Thanks
I faced this problem and with weeks of tweaking I was able to get it to work with a hack of a job... I can't remember the exact part that did fix it but will provide with what I am currently using.
Server Side
function __construct(){
parent::__construct();
header("Access-Control-Allow-Origin: " . $_SERVER['HTTP_ORIGIN']);
header("Access-Control-Allow-Credentials: true");
header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
// Access-Control headers are received during OPTIONS requests
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
header("Access-Control-Allow-Headers: X-API-KEY");
}
function available_options(){
$this->response(array('response' => array()), 200);
}
Client Side
function sendData(dataToSend, successCallback) {
window.default_headers['X-API-KEY'] = '_KEY_';
return $.ajax({
type: "POST",
url: server_url + 'user/available',
data: { data : JSON.stringify(dataToSend) }, // serializes the form's elements.
dataType: 'json',
headers: window.default_headers,
xhrFields: {
withCredentials: true
}
});
}
Since you're using a GET request, possibly using JSONP would be of more use, this avoids cross domain requests.
JSONP Request
$.ajax({
type : "GET",
dataType : "jsonp",
url: server_url + "user/available?callback=?", // ?callback=?
success: function(data){
// do stuff with data
}
});