Unable to access Microsoft Graph API after getting OAuth access_token - javascript

I'm using adal.js to generate an access token via Microsoft OAuth, however whenever I try to use the access token to call the https://graph.microsoft.com/v1.0/me endpoint (or graph.windows.net), I receive the following error: Authentication_MissingOrMalformed: Access Token missing or malformed.
Any ideas on how I can remedy this? Here's my config in JS:
<script src="https://secure.aadcdn.microsoftonline-p.com/lib/1.0.12/js/adal.min.js"></script>
<script>
var authContext = new AuthenticationContext({
instance: 'https://login.microsoft.com/',
tenant: 'xxxxxx-xxxxxxx-xxxxxx-xxxxxx', //COMMON OR YOUR TENANT ID
clientId: 'xxxxxx-xxxxxxx-xxxxxx-xxxxxx', //REPLACE WITH YOUR CLIENT ID
redirectUri: '/login.php', //REPLACE WITH YOUR REDIRECT URL
callback: getUser,
popUp: true,
cacheLocation: 'localStorage'
});
...
authContext.login();
// SET COOKIE
var newToken = authContext.getCachedToken('tenantid-xxxxxxx-xxxxxx-xxxxxx');
var now = new Date();
now.setTime(now.getTime() + 1 * 3600 * 1000);
document.cookie = "token="+newToken+"; expires=" + now.toUTCString() + "; path=/";
</script>
And here's how I'm attempting to pull/use the token in my PHP script:
<?php
// Get the token
$token = $_COOKIE['token'];
// Set headers
$headers = array(
"Authorization: Bearer " . $token,
'Content-Type: application/json'
);
// Make request to Graph API
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://graph.windows.net/mywebsite.org/me?api-version=1.6");
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$response = json_decode($response);
curl_close($ch);
echo "<pre>";
var_dump($response);
echo "</pre>";
?>
All it does is return this error: Authentication_MissingOrMalformed: Access Token missing or malformed.
How can I fix this?? Is it a problem with not specifying the correct resource?

To call the Azure AD Graph REST successfully, we need to acquire the token for the Azure AD Graph.
To check whether the token is correct for the Azure AD Graph, you can print the token and parse it from here.
The aud claim in the token should be https://graph.windows.net. If it does't match, you need to acquire the token using the acquireToken instead of getting the token from cache. And the resource parameter should be https://graph.windows.net.

Related

Login to site with PHP cURL

I'm trying login to a remote site, by having curl to the login form.
I want to redirect to another subdomain and get content.
The code I have doesn't seem to work and only tries to show the main page of the site.
<?php
$username = 'user';
$password = 'pass';
$loginUrl = 'https://site_url';
//init curl
$ch = curl_init();
//Set the URL to work with
curl_setopt($ch, CURLOPT_URL, $loginUrl);
// ENABLE HTTP POST
curl_setopt($ch, CURLOPT_POST, 1);
//Set the post parameters
curl_setopt($ch, CURLOPT_POSTFIELDS, 'user='.$username.'&password='.$password);
//Handle cookies for the login
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie.txt');
curl_setopt ($ch, CURLOPT_COOKIEFILE, 'cookie.txt');
//Setting CURLOPT_RETURNTRANSFER variable to 1 will force cURL
//not to print out the results of its query.
//Instead, it will return the results as a string return value
//from curl_exec() instead of the usual true/false.
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
//execute the request (the login)
$store = curl_exec($ch);
//the login is now done and you can continue to get the
//protected content.
//set the URL to the protected file
curl_setopt($ch, CURLOPT_URL, 'https://site_url/statistics');
//execute the request
$content = curl_exec($ch);
curl_close($ch);
//save the data to disk
file_put_contents('~/file.txt', $content);
?>
Does it have to be via cURL?
Have you considered leveraging a library like Guzzle?
They have good documentation that covers scenarios as you have described.
https://docs.guzzlephp.org/en/stable/quickstart.html#post-form-requests
Something like the below but could be laid out better
use GuzzleHttp\Client;
use GuzzleHttp\Exception\BadResponseException;
$client = new Client(['base_uri' => 'https://url_site/', 'cookies' => true]);
// Login
try {
$client->request(
'POST',
'login/',
[
'form_params' => [
'username' => $username,
'password' => $password,
],
]
);
} catch (BadResponseException $e) {
echo "Error Logging On for User {$username}";
exit;
}
// Navigate
$response = $client->request('GET', '/statistics');
$content = $response->getBody()->getContents();
file_put_contents('~/file.txt', $content);

Need to call SAP web service to send XML file from web page using JavaScript

We need to call an SAP web service from our website and submit an XML file to the SAP url. SAP API has credentials.
The purpose is to execute a function module in SAP which creates an SAP user ID and then returns the SAP user ID name back to our website via a return xml.
Below is the PHP code which i have tried.
<?php
$credentials = "Username:Password";
// Read the XML to send to the Web Service
$request_file = "m2bsubscr.XML";
$fh = fopen($request_file, 'r');
$xml_data = fread($fh, filesize($request_file));
fclose($fh);
$url = "SAP API HERE";
$headers = array(
"Content-type: text/xml;charset=\"utf-8\"",
"Accept: text/xml",
"Cache-Control: no-cache",
"Pragma: no-cache",
"SOAPAction: \"run\"",
"Content-length: ".strlen($xml_data),
"Authorization: Basic " . base64_encode($credentials)
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_USERAGENT, $defined_vars['HTTP_USER_AGENT']);
// Apply the XML to our curl call
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml_data);
$data = curl_exec($ch);
if (curl_errno($ch)) {
print "Error: " . curl_error($ch);
} else {
// Show me the result
echo "Success!<br />\n";
}
curl_close($ch);
// Handle the response from a successful request
$xmlobj = simplexml_load_string($data);
var_dump($xmlobj);
?>
My XML File:
<n0:_-majul_-m2bSubscriptionCreate xmlns:n0="urn:sap-com:document:sap:soap:functions:mc-style">
<IsSubscription>
<Bupar></Bupar>
<Sstat></Sstat>
<Categ></Categ>
<Fname>Wolfgang</Fname>
<Lname>Haerle</Lname>
<Email>whaerle#hotmail.com</Email>
<Srmrk></Srmrk>
<Cczip></Cczip>
<Cccty></Cccty>
<Ccadr></Ccadr>
<Cntry>US</Cntry>
<Product>1</Product>
<Begda>2020-07-08</Begda>
<Endda>2020-08-08</Endda>
<Price>765</Price>
<Curr>USD</Curr>
<Quantity>1</Quantity>
<Unit>MON</Unit>
<Userid></Userid>
</IsSubscription>
</n0:_-majul_-m2bSubscriptionCreate>
but it returns Success with bool(false) as a result. I tried to display error but it has no error.
Please help me to find what is the issue.
I wanted to do this in JavaScript. Kindly suggest me the way to do.

Get courses list with udemy api

Im trying to reach udemy courses list with their affiliate API and PHP.
I can get data without problem if i dont use json_decode'. When i use json_decode im getting this error.
'SyntaxError: JSON.parse: unexpected character at line 1 column 1 of
the JSON data'
function getcourse($id)
{
header('Content-Type: application/json');
$url = "https://www.udemy.com/api-2.0/courses/$id?fields[course]=#all";
// Initiate curl
$ch = curl_init();
// Disable SSL verification
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
// Will return the response, if false it print the response
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Set the url
curl_setopt($ch, CURLOPT_URL,$url);
// Execute
$c_id = base64_encode('myclientid');
$c_sid = base64_encode('myclientsecretid');
curl_setopt($ch,CURLOPT_HTTPHEADER,array('X-Udemy-Client-Id: '.$c_id.'','X-Udemy-Client-Secret: '.$c_sid.'',"Authorization: base64 encoded value of client-id:client-secret","Accept: application/json, text/plain, */*"));
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
$result=curl_exec($ch);
echo curl_getinfo($ch, CURLINFO_HEADER_OUT);
echo curl_getinfo($ch,CURLINFO_HTTP_CODE);
// Closing
curl_close($ch);
$result = json_decode($result);
return $result;
}
$cdetail = getcourse(120042);
print_r($cdetail);
I didn't get any error running your code.
You're getting this error
SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data'
Because you're using "header('Content-Type: application/json');", and you're probably using Firefox, it will think all content is json and it will verify if there is anything wrong with it.
Comment "header('Content-Type: application/json');" and you'll get your data.

Passing a cookie using cURL to a website

Some website I need to make a request to, using cURL in PHP, contains a captcha, which can be deactivated via setting a cookie "downloadcaptcha=1". Now how do I pass that cookie to the website on a cURL request? Before, you mark as duplicate, I've already made research and came across to using cookie jar files. I have never done something like that and couldn't find any newbie-friendly documentation.
The JS-equivalent code of setting the cookie, taken from the website's function that disables captchas:
var exdate=new Date();
var exdays = 1;
var c_name = "downloadcaptcha";
exdate.setDate(exdate.getDate() + exdays);
var c_value=escape(1) + ((exdays==null) ? "" : "; expires="+exdate.toUTCString());
document.cookie=c_name + "=" + c_value+";path=/";
window.location.reload();
I don't want to necessarily make it expire in 1 day.
Help is appreciated.
Here's the output. Not a single mention of the cookie
Request Header is missing the Cookie:
Host: www.emuparadise.me
Accept: */*
Accept-Encoding: deflate, gzip
Referer: https://m.emuparadise.me/
Change the $request to:
$cookie = '[downloadcaptcha=1'
$request = array();
$request[] = "Host: www.emuparadise.me";
$request[] = "Accept: */*";
$request[] = "Accept-Encoding: deflate, gzip";
$request[] = "Referer: https://m.emuparadise.me/";
$request[] = "Cookie: $cookie";
I have tried that already but the website still asks for a captcha.
Take a look at the JS code I posted. It's taken from the website's
function to disable captchas
I could help you much better if I had a URL to test with.
If there is a redirect you must use curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
You may have to make the HTTP Request Header look identical to the JS HTTP header.
You need to look at the cURL HTTP request and response and compare it to the JS HTTP request and response.
To see the JS HTTP request and response:
right click the page
Select Inspect (Chrome) or Insect Element (FireFox)
Select "Network" tab
Go to the page with the JS request or if already there Refresh.
Trouble shooting PHP code:
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
curl_setopt($ch, CURLOPT_HTTPHEADER, $request);
curl_setopt($ch, CURLOPT_ENCODING,"");
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_TIMEOUT,10);
curl_setopt($ch, CURLOPT_FAILONERROR,true);
curl_setopt($ch, CURLOPT_ENCODING,"");
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_setopt($ch, CURLOPT_HEADER, true);
$data = curl_exec($ch);
if (curl_errno($ch)){
$data .= 'Retreive Base Page Error: ' . curl_error($ch);
}
else {
$info = rawurldecode(var_export(curl_getinfo($ch),true));
$skip = intval(curl_getinfo($ch, CURLINFO_HEADER_SIZE));
$responseHeader= substr($data,0,$skip);
$response = substr($data,$skip);
var_export($info);
echo "----------------------------------\n$responseHeader\n--------------------------\n$response \n------------------------------------\n";
}
Original Post
curl_setopt($ch, CURLOPT_COOKIE, $cookie );
Single Cookie
$cookie = 'CookieName=CookieValue'
Multiple Cookies separated by semi-colon. There is no semi-colon after the last cookie.
$cookie = 'CookieName=CookieValue; CookieName=CookieValue'
curl_setopt($ch, CURLOPT_COOKIE, $cookie );
Cookies can also be set using CURLOPT_HTTPHEADER
See last line of the following example.
curl_setopt($ch, CURLOPT_HTTPHEADER, $request);
$request = array();
$request[] = "Host: www.example.com";
$request[] = "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
$request[] = "User-Agent: MOT-V9mm/00.62 UP.Browser/6.2.3.4.c.1.123 (GUI) MMP/2.0";
$request[] = "Accept-Language: en-US,en;q=0.5";
$request[] = "Connection: keep-alive";
$request[] = "Cache-Control: no-cache";
$request[] = "Pragma: no-cache";
$request[] = "Cookie: $cookie";

Soundcloud PUT API returning 401

I am trying to update soundcloud track details using HTTP API with CURL. I am getting 401 Unauthorized error as response eventhough I have passed my Client ID.
PUT https://api.soundcloud.com/tracks/11111111?client_id=12345666666
The response is
{
"errors": [
{
"error_message": "401 - Unauthorized"
}
]
}
Also wondering if I can pass access_token with the request.
If you want to pass your token, simply append "&oauth_token=" + TOKEN_VALUE
https://api.soundcloud.com/tracks/11111111?client_id=12345666666&oauth_token=YOUR_TOKEN
Edited to add example code
Here is an example of PUT using Curl & with PHP for soundcloud auth token. This code is from a working soundcloud project.
$data = array(
'code' => $token,
'client_id' => $this->getClientId(false), // your client ID
'client_secret' => $this->getClientSecret(), // your client secret
'redirect_uri' => $this->getCallback(), // callback URL
'grant_type' => 'authorization_code'
);
$url = "https://api.soundcloud.com/oauth2/token";
try {
$ch = curl_init();
// set options
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
$response = curl_exec($ch);
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$header = substr($response, 0, $header_size);
$body = substr($response, $header_size);
// read / process result
curl_close($ch);
} catch(Exception $e) {
// error handling...
}
This may work. Try turning off various CURL options. In my case I had PUT working under PHP5.5 but after migrating to new server with PHP7 the POST operation would fail until I set CURLOPT_SAFE_UPLOAD to false for soundcloud POST operations (file uploads); however after making this change to all my curl inits, my PUT operations failed because they also had safeupload set to false, so I removed this setting from my PUT operations and the PUT operations started working.
In short, try turning off SAFE UPLOAD option for your PUT operations.
More info about this curl option on this post.

Categories

Resources