I am using Microsoft graph API to retrieve my messages from Microsoft account using php SDK (https://github.com/microsoftgraph/msgraph-sdk-php).
My code sample is given below
<?php
// Autoload files using the Composer autoloader.
require_once __DIR__ . '/vendor/autoload.php';
use Microsoft\Graph\Graph;
use Microsoft\Graph\Model;
//get the access token to access graph api
$tenantId = "XXXXXX";
$clientId = "XXXXXXXXXXXX";
$clientSecret = "XXXXXXXXXXX";
$guzzleClient = new \GuzzleHttp\Client(array('curl' => array( CURLOPT_SSL_VERIFYPEER => false)));
$url = 'https://login.microsoftonline.com/' . $tenantId . '/oauth2/token?api-version=1.0';
$token = json_decode($guzzleClient->post($url, [
'form_params' => [
'client_id' => $clientId,
'client_secret' => $clientSecret,
'resource' => 'https://graph.microsoft.com/',
'grant_type' => 'client_credentials',
],
])->getBody()->getContents());
$accessToken = $token->access_token;
//get the messages of user
$graph = new Graph();
$graph->setAccessToken($accessToken);
$messages = $graph->createRequest("GET", "/me/messages")
->setReturnType(Model\User::class)
->execute();
print_r($messages); exit;
But it throws me error as shown below :
Fatal error: Uncaught GuzzleHttp\Exception\ClientException: Client error: GET https://graph.microsoft.com/v1.0/me/messages resulted in a 400 Bad Request response: { "error": { "code": "BadRequest", "message": "Current authenticated context is not valid for this request. (truncated...) in C:\wamp64\www\graph_api\vendor\guzzlehttp\guzzle\src\Exception\RequestException.php on line 113
Is this because of any permission problem to access the Graph API? I have the following permissions set in the Microsoft app registration portal
As well as in azure portal
What may cause this issue? Any way to solve the problem?
You are getting the exception:
Current authenticated context is not valid for this request
since the acquired token is for application permissions (client credentials flow). In this flow, there is no context for Me since it represents signed-in user context.
To get messages in client credentials flow user needs to be explicitly resolved in endpoint:
https://graph.microsoft.com/v1.0/users/{user-id}/messages
Example
$userId = "--user-id-goes-here--";
$messages = $graph->createRequest("GET", "/users/{$userId}/messages")
->setReturnType(\Microsoft\Graph\Model\User::class)
->execute();
Related
I'm using Microsoft Graph Api (PHP->msGraph SDK) to create online meetings.
I'm Facing 403 error can someone help me out.
$clientId = "***********************************";
$clientSecret = "***********************************";
$tenantId = '***********************************';
$responseUri = "http://localhost:8888/moodle39";
$guzzle = new \GuzzleHttp\Client();
$url = 'https://login.microsoftonline.com/' . $tenantId . '/oauth2/v2.0/token';
$token = json_decode($guzzle->post($url, [
'form_params' => [
'client_id' => $clientId,
'client_secret' => $clientSecret,
'scope' => 'https://graph.microsoft.com/.default',
'grant_type' => 'client_credentials',
],
])->getBody()->getContents());
$accessToken = $token->access_token;
//Create a new Graph client.
$graph = new Graph();
$graph->setAccessToken($accessToken);
$onlinemeet->startDateTime = "2020-09-02T14:30:34.2444915";
$onlinemeet->endDateTime = "2020-09-02T15:30:34.2444915";
$onlinemeet->subject = "Test Meeting";
$jso = json_encode($onlinemeet);
$user = $graph->createRequest("POST", "/me/onlineMeetings")->addHeaders(array("Content-Type" => "application/json"))->attachBody($jso)->setReturnType(User::class) ->execute();
Exception - Client error: POST https://graph.microsoft.com/beta/me/onlineMeetings resulted in a 403 Forbidden response: { "error": { "code": "Forbidden", "message": "", "innerError": { "request-id": "bd43aa57-511e-4 (truncated...)
While creating an application in azure portal
under API permission i gave permission to access
GraphApi->Delegated Permissions->onlinemeetings.ReadWrite.
Can someone help me with a proper example or proper syntax in PHP.
Thankyou !!..
You cannot use the client credential flow to get the token to call the /me endpoint. For the client credential flow, it is usually used for server-to-server interactions that must run in the background and do not interact with the user immediately(No user logged in). For the /me endpoint, it is usually User login is required, so you should use auth code flow.
By the way, APIs under the /beta version in Microsoft Graph are subject to change. Use of these APIs in production applications is not supported. Therefore, it is recommended that you use the /v1.0 version.
please see:here.
Update:
There are many similar samples, I hope they can help you:
OAuth 2.0 PHP Sample Code.
Authentication and Authorization Using Auth0 in PHP.
I want to configure my Symfony4 application to read and send e-mails using the msgraph-sdk-php library.
My app would be reading and sending e-mail from a single account, whose password I don't want to expose to my app's users. Thus, I wouldn't be using OAuth for login.
My first experience was this piece of code (to retrieve mailbox user profile):
<?php
namespace App\Graph;
use Microsoft\Graph\Exception\GraphException;
use Microsoft\Graph\Graph;
use Microsoft\Graph\Model\User;
class GraphService
{
function sentTestMessage() {
$userId = "************************************";
$tenantId = "************************************";
$clientId = "************************************";
$clientSecret = "***************************";
$guzzle = new \GuzzleHttp\Client();
$url = 'https://login.microsoftonline.com/' . $tenantId . '/oauth2/token?api-version=1.0';
$token = json_decode($guzzle->post($url, [
'form_params' => [
'client_id' => $clientId,
'client_secret' => $clientSecret,
'resource' => 'https://graph.microsoft.com/',
'grant_type' => 'client_credentials',
],
])->getBody()->getContents());
$accessToken = $token->access_token;
$graph = new Graph();
$graph->setAccessToken($accessToken);
$user=new \stdClass();
try {
$user = $graph->createRequest("GET", "/users/".$userId)
->setReturnType(User::class)
->execute();
} catch (GraphException $e) {
$user->getGivenName=$e->getMessage();
}
return "Hello, I am $user->getGivenName() ";
}
}
But then Symfony shows me an exception page with this message:
Client error: GET https://graph.microsoft.com/v1.0/users/... resulted in a 403 Forbidden response:
{
"error": {
"code": "Authorization_RequestDenied",
"message": "Insufficient privileges to complete the ope (truncated...)
Now the same query works when run in https://developer.microsoft.com/en-us/graph/graph-explorer with the same user logged in.
These are the permissions I gave the app:
What should I do to overcome the problem above described?
You used client credentials flow to get access token in your code, so you need application permission instead of delegated permission.
I have tried a lot to find out my issue but no luck there.
I am using Guzzle for my authentication and it's giving me the token. So there is no issue. The problem is while i am trying to get data it is showing me
" An uncaught Exception was encountered
Type: GuzzleHttp\Exception\ClientException
Message: Client error: GET https://graph.microsoft.com/v1.0/me resulted in a 400 Bad Request response: { "error": { "code": "BadRequest", "message": "Current authenticated context is not valid for this request. (truncated...) "
Here is my code below
$url = 'https://login.microsoftonline.com/' . $tenantId . '/oauth2/token?api-version=1.0';
$token = json_decode($guzzle->post($url, [
'form_params' => [
'client_id' => $appId,
'client_secret' => $appSecret,
'resource' => 'https://graph.microsoft.com/',
'grant_type' => 'client_credentials',
],
])->getBody()->getContents());
$accessToken = $token->access_token;
$graph = new Graph();
$graph->setAccessToken($accessToken);
$user = $graph->createRequest("GET", "/me")
->setReturnType(Model\User::class)
->execute();
echo "Hello, I am $user->getGivenName() ";
Note: I have successfully got the token, and i am using CodeIgniter framework where CSRF is false. Also i have given the permission for the app User.Read.All, User.ReadWrite.All
Please help me out to solve of this problem.
Thanks in advance.
You cannot call /me using Client Credentials. The purpose of the Client Credentials is to authenticate an application without a user. Therefore there is no way for the API to translate which user you mean when you call /me.
In my PHP application, users provide their own Facebook Application ID and Application Secret. I need to validate them and display nice error if they are invalid.
I already found a nice way to do it. I can make a request to https://graph.facebook.com/oauth/access_token?client_id=123456&client_secret=abcdefg&grant_type=client_credentials
If credentials are invalid, the response is as follows:
{
"error": {
"message": "Error validating application. Cannot get application info due to a system error.",
"type": "OAuthException",
"code": 101,
"fbtrace_id": "D8oHjJoc2Nc"
}
}
I'm confused about the ways to do it with PHP SDK. There's a neat get() method to make such a request, but I'm not sure how to send request without authorizing the application. This is what I did:
$app = new Facebook\FacebookApp( $app_id, $app_secret );
$access_token = $app->getAccessToken();
$query = http_build_query([
'client_id' => $app_id,
'client_secret' => $app_secret,
'grant_type' => 'client_credentials',
]);
$facebook = new Facebook\Facebook( [
'app_id' => $app_id,
'app_secret' => $app_secret,
'default_graph_version' => '2.5',
] );
$response = $facebook->get( '/oauth/access_token?' . $query, $access_token );
I'm getting the following error:
Unknown path components: /oauth/access_token
But even if it worked, it's strange to call it with any sender credentials. Is it possible to make an "anonymous" Facebook request with PHP SDK?
The SDK implicitly adds the API version number specified to the path in -> get(), so I think that's causing your error here because the underlying call is being made to /2.5/oauth/access_token (fails for me in a browser)
It should be /v2.5/oauth/access_token (works for me in a browser)
Update default_graph_version to v2.5 and try that
I have been trying to implement a simple authentication flow using OAuthv1.a and bit bucket. My issue occurs when I make a request for access tokens using the previously supplied verifier and oauth_token. I am always given a 400 error with no real indication as to why.
Client error response
[status code] 400
[reason phrase] BAD REQUEST
[url] https://bitbucket.org/api/1.0/oauth/access_token?oauth_consumer_key=<snip>&oauth_nonce=fba24cfb3147ca7d32b3924fad43fd509bbb9bc1&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1381034857&oauth_token=fFz369NUmCHNyn7PGj&oauth_verifier=6724267371&oauth_version=1.0&oauth_signature=1H7%2Bvx0fVh2Sj%2FcDAE2QzkTx8us%3D
I am using the OauthPlugin class within guzzle to build signed parameters and submitting post requests as described in the documentation. Has anyone had an issue like this with any other OAuthv1 provider or Bit Bucket specifically?
$client = new Client('https://bitbucket.org/api/1.0/');
$oauth = new OauthPlugin( array(
'request_method' => OauthPlugin::REQUEST_METHOD_QUERY,
'consumer_key' => Config::get('oauthv1.key'),
'token' => Input::get('oauth_token'),
'verifier' => Input::get('oauth_verifier')
)
);
$client->addSubscriber($oauth);
$client->post('oauth/access_token')->send();
Even though the Bitbucket API documentation doesn't mention it, the call to the oauth/access_token endpoint also requires the consumer_secret and oauth_token_secret. The consumer secret is generated by Bitbucket when you create your app and should be stored in your config. You can get the oauth_token_secret from the response of the call to oauth/request_token. Just save it in the session so you can use it when getting the access token.
Request a request token:
$client = new Client('https://bitbucket.org/api/1.0');
$oauth = new OauthPlugin(array(
'consumer_key' => $app['bitbucket.key'],
'consumer_secret' => $app['bitbucket.secret'],
'callback' => 'http://mysite.local/callback',
));
$client->addSubscriber($oauth);
$response = $client->post('oauth/request_token')->send();
// Parse the response
parse_str($response->getBody(), $result);
// Save the token secret in the session
$app['session']->set('oauth_token_secret', $result['oauth_token_secret']);
// Redirect to Bitbucket to authorize the application
return $app->redirect(sprintf('https://bitbucket.org/api/1.0/oauth/authenticate?oauth_token=%s', $result['oauth_token']));
Request an access Token:
$token = $app['request']->get('oauth_token');
$verifier = $app['request']->get('oauth_verifier');
$tokenSecret = $app['session']->get('oauth_token_secret');
$client = new Client('https://bitbucket.org/api/1.0');
$oauth = new OauthPlugin(array(
'consumer_key' => $app['bitbucket.key'],
'consumer_secret' => $app['bitbucket.secret'],
'token' => $token,
'token_secret' => $tokenSecret,
'verifier' => $verifier,
));
$client->addSubscriber($oauth);
$client->post('oauth/access_token')->send();
// Parse the response
$response = parse_str($response->getBody(), $result);
// Get the access token
$accessToken = $result['oauth_token'];