Microsoft Authentication: How to refresh access token using ajax post? - ajax

I've been going through the app authorization steps here https://developer.microsoft.com/en-us/graph/docs/authorization/app_authorization, but can't seem to get the request to work. I consistently get errors saying
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access."
This seems weird as I am including that header.
$.ajax({
type: "POST",
url: url,
crossDomain: true,
data: {
'refreshToken': refreshToken,
'client_id': clientId,
'client_secret': clientSecret,
'redirect_uri': redirect_uri,
'resource': resource
},
dataType: 'json',
beforeSend: function (xhr) {
xhr.setRequestHeader('Access-Control-Allow-Origin', "*");
xhr.setRequestHeader('Access-Control-Allow-Methods', "*");
xhr.setRequestHeader('Access-Control-Allow-Headers', "*");
},
success: function (data, status, headers, config) {
callback(data);
},
error: function (data, status, headers, config) {
console.log('Error getting access token from Microsoft Graph: ' + status + " " + JSON.stringify(data));
}
});

You are using a wrong OAuth2 flow. You should not use the Authorization grand code flow in browser applications, because you cannot keep the client secret safe and the tokens get to the server when a browser requests the redirect URL (the tokens are not in the hash # part of the URL).
That's why Microsoft API doesn't support XHR access to the /token endpoint (by omitting the CORS response headers).
You could consider using the Implicit flow, which is designed for usage in browsers, keeps the tokens safe and doesn't require a client secret.

Related

Facebook graph api Request header field authorization is not allowed

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.

NTLM is automatically added instead of Bearer in AJAX Calls while calling API

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).

Tibco Spotfire basic authentication with cross domain ajax call

I am creating a client side session using cross domain ajax call to Spotfire server. For authentication I am using basic authentication method. When I make my request through Postman with Authorization header and value 'Basic ' + btoa('user:password') it send correct header and start a new session, whereas in web browser it shows error as
NetworkError: 405 Method Not Allowed -
http://server-path/GetJavaScriptApi.ashx?Version=8.0
&
Cross-Origin Request Blocked: The Same Origin Policy disallows reading
the remote resource at
http://server-path/GetJavaScriptApi.ashx?Version=8.0.
(Reason: CORS header ‘Access-Control-Allow-Origin’ missing).
This was because in cross domain ajax call first OPTIONS request is made followed by POST/GET, to overcome this I made dataType: "jsonp" in my ajax call. Now GET calls are working but now gives me a new error:
The resource from
“http://server-path/GetJavaScriptApi.ashx?Version=8.0&callback=jQuery111107482621169238032_1487159470493&_=1487159470494”
was blocked due to MIME type mismatch (X-Content-Type-Options:
nosniff).
Ajax code is as follows:
$.ajax({
url: 'https://server-path/GetJavaScriptApi.ashx?Version=8.0',
type: 'GET',
crossDomain: true,
beforeSend: function(xhr) {
xhr.setRequestHeader("Authorization", Basic ' + btoa('user:password'));
xhr.setRequestHeader("content-type", 'text/plain');
xhr.setRequestHeader("X-Content-Type-Options", "nosniff");
},
dataType: "jsonp",
success: function (jsonData) {
console.log(jsonData);
},
});
Call to https://server-path/GetJavaScriptApi.ashx?Version=8.0 return javascipt as response after successful authentication
Please help to resolve.. Thanks

Cross domain ajax hits error even that the status came back is 200

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.

Cross-Domain ajax error with bearer authentication - 401 Unauthorized

So... i'm making a cross domain (CORS) call. When i initially make it on the page, it works just fine (noting that cross-domain issues aren't really a problem), but when i make another request later to the same server adding a bearer authorization token to the header, it is failing with a 401 Unauthorized.
Also, when i run this code from the same domain, both calls run successfully (identifying that the token is ok...)
Thoughts?
$.ajax({
url: apiPath.userMetaUrl(),
xhrFields: {
withCredentials: true
},
cache: false,
error: function (xhr, ajaxOptions, thrownError) {
console.log("url: " + apiPath.userMetaUrl());
console.log("fn loadUserMetaData xhr.status: " + xhr.status);
console.log("fn loadUserMetaData xhr.responseText: " + xhr.responseText);
console.log("fn loadUserMetaData thrownError: " + thrownError);
},
dataType: "json",
jsonpCallback: "callback",
beforeSend : setHeader,
success: function (data) {
//woohoo!
}
}
function setHeader(xhr) {
xhr.setRequestHeader('Authorization', 'Bearer ' + authenticatedInfo.access_token);
}
Again, running this code from same domain as apiPath.userMetaURL() works fine. On a different domain, the initial call without adding request header works fine. Access-Control-Allow-Orign has the cross-domain URL added. Access-Control-Allow-Headers has Authorization added.
xhr.status returns 0 and responseText/thrownError are blank.
JSONP != ajax
These requests you are making are simply adding <script> tags to your DOM. It's just wrapped in an ajax syntax for ease of use. You can't modify the request headers in this fashion. You need to create a CORS ajax request, and configure your server to handle them.
Executing jsonp requests on the same domain though... I believe jQuery just uses an xmlHttpRequest though. For cross-domain, it uses <script> tags. This would explain the behavior you are seeing.
Consider the following.
$.ajax({
url: 'http://google.com',
dataType: 'jsonp',
beforeSend: function(xhr) { xhr.setRequestHeader('foo', 'bar'); }
});
Look at your network traffic. It will create the request, but you will not see the foo header.

Resources