microsoftgraph/msgraph-sdk-php

$graphClient->me()->drive() get invalid garant

Opened this issue · 1 comments

Hy

i try to upload files to my onedrive with php. It didn't work....

I get a token. But the upload client get "invalid garant"...

my script (the fail is on line 74):


<?php            
  

require_once 'vendor/autoload.php';
require_once 'vendor/guzzlehttp/psr7/vendor/autoload.php';

use GuzzleHttp\Client;
use GuzzleHttp\Handler\MockHandler;
use GuzzleHttp\Psr7\Response;    
use League\OAuth2\Client\Token\AccessToken;
use Microsoft\Graph\Core\Authentication\GraphPhpLeagueAccessTokenProvider;
use Microsoft\Graph\Core\Authentication\GraphPhpLeagueAuthenticationProvider;
use Microsoft\Graph\Core\NationalCloud;
use Microsoft\Graph\GraphRequestAdapter;
use Microsoft\Graph\GraphServiceClient;
use Microsoft\Kiota\Abstractions\Authentication\AnonymousAuthenticationProvider;
use Microsoft\Kiota\Authentication\Cache\InMemoryAccessTokenCache;
use Microsoft\Kiota\Authentication\Oauth\AuthorizationCodeContext;
use Microsoft\Kiota\Authentication\Oauth\ClientCredentialContext;
use Microsoft\Kiota\Http\GuzzleRequestAdapter;
use PHPUnit\Framework\TestCase;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Client\NetworkExceptionInterface;

use GuzzleHttp\Psr7;
use GuzzleHttp\Psr7\Stream;
use Microsoft\Graph\Model\Message;

use Microsoft\Graph\Core\Tasks\LargeFileUploadTask;
use Microsoft\Graph\Generated\Drives\Item\Items\Item\CreateUploadSession\CreateUploadSessionPostRequestBody as DriveItemCreateUploadSessionPostRequestBody;
use Microsoft\Graph\Generated\Models;
use Microsoft\Graph\Generated\Users\Item\Messages\Item\Attachments\CreateUploadSession\CreateUploadSessionPostRequestBody as AttachmentCreateUploadSessionPostRequestBody;

$client_id = "71dxxxxxxxxxxxxxxxxx";
$client_secret = "xxxxxxxxxxxxxxxxxxxxxxxxxx";
$tenat = "f8cdxxxxxxxxxxxxxxx"; //tested ut with common. didn't help
    
	//Authenticate
    $guzzle = new \GuzzleHttp\Client();
    $url = "https://login.microsoftonline.com/" . $tenat . "/oauth2/v2.0/token";
	
    $token = json_decode($guzzle->post($url, array('form_params' => array('client_id' => $client_id, 'client_secret' => $client_secret, 'scope' => 'https://graph.microsoft.com/.default', 'grant_type' => 'client_credentials')))->getBody()->getContents());
	$access_token = $token->access_token;
    
	
	//ServerClient
	$tokenRequestContext = new AuthorizationCodeContext('common',$client_id,$client_secret,$access_token ,'http://localhost/test1/src/test3/test.php');
	$scopes = ['Files.ReadWrite.All'];
	$graphServiceClient = new GraphServiceClient($tokenRequestContext, $scopes);
	
//echo '<pre>' . var_export($graphServiceClient, true) . '</pre>';
   			
    //upload
	
	
						function uploadFileToOneDrive(GraphServiceClient $graphClient, string $filePath, string $itemPath): void {
								// <LargeFileUploadSnippet>
								// Create a file stream
								$file = Psr7\Utils::streamFor(fopen($filePath, 'r'));

								// Create the upload session request
								$uploadProperties = new Models\DriveItemUploadableProperties();
								$uploadProperties->setAdditionalData([
									'@microsoft.graph.conflictBehavior' => 'replace'
								]);

								// use Microsoft\Graph\Generated\Drives\Item\Items\Item\CreateUploadSession\CreateUploadSessionPostRequestBody
								// as DriveItemCreateUploadSessionPostRequestBody;
								$uploadSessionRequest = new DriveItemCreateUploadSessionPostRequestBody();
								$uploadSessionRequest->setItem($uploadProperties);

								// Create the upload session
								/** @var Models\Drive $drive */
								$drive = $graphClient->me()->drive()->get()->wait();
								
								$uploadSession = $graphClient->drives()
									->byDriveId($drive->getId())
									->items()
									->byDriveItemId('root:/'.$itemPath.':')
									->createUploadSession()
									->post($uploadSessionRequest)
									->wait();

								$largeFileUpload = new LargeFileUploadTask($uploadSession, $graphClient->getRequestAdapter(), $file);
								$totalSize = $file->getSize();
								$progress = fn($prog) => print('Uploaded '.$prog[1].' of '.$totalSize.' bytes'.PHP_EOL);

								try {
									$largeFileUpload->upload($progress)->wait();
								} catch (\Psr\Http\Client\NetworkExceptionInterface $ex) {
									$largeFileUpload->resume()->wait();
								}
								// </LargeFileUploadSnippet>

								// Added to remove warning about unused function
								if (is_null($uploadSession)) {
									LargeFileUpload::resumeUpload($largeFileUpload);
								}
							}
							
							
							
	uploadFileToOneDrive($graphServiceClient, "test.txt", "test.txt");
	
	
?>

please give me some help. I works since two weeks....

in microsoft i add a app and created the client id.
this are my permissons:
image

Hi @Jumbo125
Thanks for reaching out.

For your app to receive the delegated permissions, a user needs to sign in first. You would need to redirect your user to log-in by hitting the endpoint to get an authorization code: see docs for the URL

Using the code returned, you can now pass that to the AuthorizationCodeContext.

Currently, your code is requesting an access token using the client_credentials grant, which doesn't work for Delegated permissions but for application permissions, then passing the access token to the AuthorizationCodeContext, instead of passing an authorization code.

Feel free to reach out in case you need more help.