OneDrive file access with php using microsoft graph - php

I tried using the library from krizalys for an implementation to read and write files from OneDrive. It should work for business accounts but would be nice if it could also work for personal accounts.
Since I read that the Live SDK used in krizalys example will be offline soon (as mentioned here), I tried implementing Microsoft Graph instead.
I implemented two ways to get an access token at the moment, one with grant type password (getAccessToken Method from this sample used) and one with client_credentials (Like in the krizalys lib). Both seem to work and return an access_token and refresh_token, but when I try to make a request I get the message:
"InvalidAuthenticationToken [message] => Access token is empty"
The code for my request:
$data = array("name" => "test");
$url = "https://graph.microsoft.com/v1.0/me/drive/root";
$client = new \GuzzleHttp\Client();
$response = $client->request('POST', $url, [
'headers' => [
'Authorization: Bearer ' . $this->_state->token->data->access_token,
'Content-Type: application/json',
'Content-Length: ' .strlen(json_encode($data))
],
'body' => json_encode($data),
]);
I also tried it with the GET method and added the Host: graph.microsoft.com to ensure that this is not the problem:
$url = "https://graph.microsoft.com/v1.0/me";
$client = new \GuzzleHttp\Client();
$response = $client->request('GET', $url, [
'headers' => [
'Authorization: Bearer ' . $this->_state->token->data->access_token,
'Host: graph.microsoft.com'
],
]);
The token response payload looks like this:
The application is configured at https://apps.dev.microsoft.com and the permissions are set. Is there anything wrong with my request? I have no idea why I always get the InvalidAuthenticationToken message. Thanks.

You've registered your application in the v2 Endpoint (apps.dev.microsoft.com) but the sample code you're using is for the v1 Endpoint. These are not interchangeable. Also, password isn't a valid OAuth Grant for the v2 Endpoint (v2 supports authorization_code, implicit, and client_credentials)
You need to obtain your token from the v2 Endpoint. You might find these articles helpful:
Microsoft v2 Endpoint Primer.
Azure AD v2.0 Overview

Related

Azure/Microsoft Identity Platform - Cannot Retrieve Access Token from Token Endpoint (PHP)

I'm trying to write a custom web app that utilizes the Microsoft Identity Platform to authenticate and authorize users. I'm able to successfully authenticate when calling the /authorize endpoint, and I have access to the "code" token that is returned.
I am now trying to retrieve my access token so that I can make calls to the APIs. Whenever I submit a POST request to the /token endpoint, the server returns a 400 Bad Request error. The header information that is provided contains no valuable information for troubleshooting and there is no JSON response returned so I have no idea where or what the issue is.
I'm making my call as follows:
$clientId = '00000000-0000-0000....'; // Omitted
$tenantId = '00000000-0000-0000....'; // Omitted
$grantType = 'authorization_code';
$scope = urlencode('User.Read');
$code = '......' // Obtained from authentication
$redirect_uri = 'http://localhost/smp/auth/handle';
$clientSecret = '...' // Omitted, set up in Azure App registrations under Certificates and secrets
$resource = 'api://00000000-0000-0000....'; // Omitted, set up in Azure App registrations under Overview -> App ID URI
$url = "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token";
$parameters = [
'client_id' => $clientId,
'grant_type' => $grantType,
'scope' => $scope,
'code' => $code,
'redirect_uri' => $redirectUri,
'client_secret' => $clientSecret,
'resource' => $resource
];
$options = [
'http' => [
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => http_build_query($parameters)
]
];
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
if (!$result) {
exit('an error has occured');
}
PHP returns a warning that reads the following: (tenant id has been omitted):
Warning: file_get_contents(https://login.microsoftonline.com/00000000-0000-0000-0000-000000000000/oauth2/v2.0/token): Failed to open stream: HTTP request failed! HTTP/1.1 400 Bad Request in C:\xampp\htdocs\smp\application\models\user-model.php on line 261
I've verified everything I can possibly think of.
The client and tenant ids are working (based on the successful authentication request).
The "code" is correctly retrieved from the authentication request.
Redirect Uri is the same as the one used for the authentication request.
I've tried with and without the client_secret variable. It is my understanding that this is actually required in my case.
I've tried with and without the resource variable, which is setup using the default Azure naming convention of "api://".
Please assist! I know I must be missing something but cannot figure it out. Perhaps permissions or additional setup within Azure? I'm not really sure what's wrong with my code/approach but Microsoft Identity Platform/OAuth isn't returning anything for me to work with and/or troubleshoot.
I've figured this out.
Firstly, I modified by $options variable to include the following:
$options = [
'http' => [
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => http_build_query($parameters),
'ignore_errors' => true
]
];
Adding ignore_errors allowed me to see the returned JSON.
Next, it became apparent that my parameters were not being accepted because I was url-encoding all of them. My client secret, redirect uri, and client ids were all url encoded (this detail was hidden in my original post because it was just a small snippet of a much larger system). By undoing this encoding, my parameters all ended up being accepted. I suppose it makes sense because these values weren't being appended to a url but rather passed as POST values.
Lastly, the "resource" variable was not accepted (indeed, it wasn't required). Not sure if any of this is going to help anyone else but just in case, this was my fix.

Problem with Azure AD authentication - Bearer token returns only app information

I have a problem implementing Azure AD SSO for my website.
The Azure AD configuration uses a certificate instead of a secret. Everything looks to be working, but https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token returns a Bearer token which contains only app information and I'm trying to get the user information for the user who has logged in.
Can anyone provide me some information and tips how to obtain user information?
Code for getting Bearer token:
public function getAccessToken(){
$link = "https://login.microsoftonline.com/{$this->tenantId}/oauth2/v2.0/token";
$request_headers = array(
'Accept: application/x-www-form-urlencoded'
);
$post_data = array(
"client_id" => $this->clientId,
"grant_type" => "client_credentials",
"client_assertion_type" => "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
"client_assertion" => $this->jwToken,
"scope" => "https://graph.microsoft.com/.default",
"code" => $this->responseCode,
"redirect_uri" => $this->redirectUri,
);
$curlResponse = $this->sendCURLRequest($link, $request_headers, $post_data);
var_export($curlResponse);
}
As #juunas suggested, you should use authorization code flow rather than client credentials flow.
Now that you have got the code from Request an authorization code, next you need to Redeem a code for an access token.
POST /{tenant}/oauth2/v2.0/token HTTP/1.1
Host: https://login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded
client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&scope=https%3A%2F%2Fgraph.microsoft.com%2Fmail.read
&code=OAAABAAAAiL9Kn2Z27UubvWFPbm0gLWQJVzCTE9UkP3pSx1aXxUjq3n8b2JRLk4OxVXr...
&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F
&grant_type=authorization_code
&code_verifier=ThisIsntRandomButItNeedsToBe43CharactersLong
&client_secret=JqQX2PNo9bpM0uEihUPzyrh // NOTE: Only required for web apps. This secret needs to be URL-Encoded.
What you have used is Client credentials flow get token, in which you don't need the code.

Microsoft Graph SSO Azure AD not redirecting user to Login page

Sorry but I am just learning about Microsoft Graph and I have spent the last 4 hours scouring Google to find my answer and my brain is going to explode so I have resorted to Stack.
I was using a previous method to authenticate a user to Azure AD but it has no more support and I want to switch over to Microsoft Graph. I am able to get the access token but that is as far as I get.
At this point all I want to do send the user to the Microsoft Login page so they can authenticate and be redirected back to my web app. I have read so much I don't know what else I can read. Is there anyone who can point me in the right direction to how to get this accomplished? also where in the world is the documentation for this?
$guzzle = new \GuzzleHttp\Client();
$tenantId = "***********************************";
$url = 'https://login.microsoftonline.com/' . $tenantId . '/oauth2/token?api-version=1.0';
$token = json_decode($guzzle->post($url, [
'form_params' => [
'client_id' => '***********************************',
'client_secret' => '***********************************',
'resource' => 'https://graph.microsoft.com/',
'grant_type' => 'client_credentials',
'redirect_uri' => 'https://www.example.com/here'
],
])->getBody()->getContents());
$accessToken = $token->access_token;
// Create a new Graph client.
$graph = new Graph();
$graph->setAccessToken($accessToken);
Comment moved to answer:
As I said in the comments, if you need to log in as a user and authenticate, please don't use a daemon-based client credential flow because there is no user interaction with this flow. You should use the authentication code flow, which requires you to log in to the user and obtain the authorization code, and then use the authorization code to redeem the access token.
Sample for your referenceļ¼š
OAuth 2.0 PHP Sample Code.
Authentication and Authorization Using Auth0 in PHP.
Microsoft Graph Connect Sample for PHP.

How to Set Xero Authorization Header Using wp_remote_post()

I am trying to use the Xero API to send an Invoice Email on my WordPress site. But I am unsure how to set the authorization header I have attempted the following:
$args = array(
'headers' => array(
'Content-Type: application/x-www-form-urlencoded',
'Authorization' => 'Basic ' . base64_encode('myClientID' . ':' . 'myClientSecret')
),
);
$response = wp_remote_post('https://api.xero.com/api.xro/2.0/Invoices/2dfa4120-1fd2-4e67-927e-c16ac821226c/Email', $args);
print_r($response);
This gives me a response of 404 unauthorized. Is there something I'm missing or doing wrong?
the Authorization header actually requires a valid access_token be set, not the id / secret combo. You can read more about the code flow required to get a token here: https://developer.xero.com/documentation/oauth2/auth-flow
If you familiar with PHP you can look through code in the PHP SDK sample app here: https://github.com/XeroAPI/xero-php-oauth2-app
Is your goal to send that invoice email to a dynamic organisation, or simply send an invoice from your own personal org?
Fortunately (or unfortunately) early next year we will have the option for this embedded access_token - but if you wanted to set this up in the interim you will need to generate an access token from a user flow, and then setup the backend mechanism to have it be refreshed prior to usage which I explain in this youtube vid: https://www.youtube.com/watch?v=Zcf_64yreVI
More about "machine 2 Machine" integrations aka the client_credentials OAuth2.0 grant
https://developer.xero.com/announcements/custom-integrations-are-coming/

Unable to get token from Bot Framework

Since few days, I'm unable to get a token from Microsoft Bot Framework Web Chat API.
I do a GET request to https://webchat.botframework.com/api/tokens with PHP. I set the header Authorization to BotConnector MY_SECRET :
$options = array('http' => array(
'method' => 'GET',
'header' => 'Authorization: BotConnector ' . $secret
));
$context = stream_context_create($options);
$token = file_get_contents('https://webchat.botframework.com/api/tokens', false, $context);
The server answer is: "HTTP request failed! HTTP/1.1 405 Method Not Allowed".
My secret key is valid, I try also with a POST request but the server answers the same result.
If I call the Web Chat iFrame with my Secret Key, all works great but it's not secure.
This was a temporary bug/regression, I reported it and it's now fixed. The service should work as documented.
https://github.com/Microsoft/BotBuilder/issues/1556#issuecomment-257333517

Categories