phpazuremicrosoft-graph-api

I have try to create event in microsoft outlook calendar but coming error Access token validation failure. Invalid audience


I have tried to create event in microsoft outlook calendar but coming error

 {"error":{"code":"InvalidAuthenticationToken","message":"Access token validation failure. Invalid audience.","innerError":{"date":"2025-01-02T12:23:03","request-id":"8e700f58-302f-4aad-bb63-eb5283171d1d","client-request-id":"8e700f58-302f-4aad-bb63-eb5283171d1d"}}}

this is my code we have generated access token perfectly and test with jwt.io site and perfect token is validated but when i added this token in my code coming above error, and i have added all type of permission in the my azure portal directory, i think i miss 1 normal thing but i don't know what

$accessToken = 'this is tested and valid signature perfect token' tested by jwt.io site $targetUserId = 'my outlook email address'

// Event details
        $eventDetails = [
            'summary' => 'Event Subject',
            'description' => 'Event Description',
            'start' => [
                'dateTime' => date('Y-m-d\TH:i:s', time()), // current date and time
                'timeZone' => 'UTC', // adjust time zone if needed
            ],
            'end' => [
                'dateTime' => date('Y-m-d\TH:i:s', time() + 3600), // one hour later
                'timeZone' => 'UTC', // adjust time zone if needed
            ],
            'location' => 'Event Location',
        ];

        // Prepare the data for the API request
        $postFields = json_encode([
            'subject' => $eventDetails['summary'],
            'body' => [
                'contentType' => 'HTML',
                'content' => $eventDetails['description'],
            ],
            'start' => [
                'dateTime' => $eventDetails['start']['dateTime'],
                'timeZone' => $eventDetails['start']['timeZone'],
            ],
            'end' => [
                'dateTime' => $eventDetails['end']['dateTime'],
                'timeZone' => $eventDetails['end']['timeZone'],
            ],
            'location' => [
                'displayName' => $eventDetails['location'],
            ],
        ]);

        // Set the cURL options for the POST request to the Graph API
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, "https://graph.microsoft.com/v2.0/users/{$targetUserId}/events");
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $headers = array();
        $headers[] = 'Authorization: Bearer '.$accessToken;
        $headers[] = 'Content-Type: application/json';
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        //~ curl_setopt($ch, CURLOPT_HTTPHEADER, ['Authorization' => 'Bearer '.$accessToken, 'Content-Type' => 'application/json']);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields);
        curl_setopt($ch, CURLOPT_VERBOSE, true);

        // Execute the request and get the response
        $response = curl_exec($ch);
        curl_close($ch);

        // Handle the response (error handling and logging may be added here)
        if ($response === false) {
            echo 'Error creating event.';
        } else {
            echo 'Event created successfully: ' . $response;
        }

Token generation code

curl --location --request POST 'https://login.microsoftonline.com/$tenant-id/oauth2/v2.0/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=f66eccc4-7397....' \
--data-urlencode 'scope=f66eccc4-7397-4c3a-9999-36d2d3156788/.default' \
--data-urlencode 'refresh_token=1.ASwA67m7Og_3jUOZPNoq_CfpiMTMbvaXczpMmZk20tMVZ4gsAMIsAA.AgABAwEAAADW6jl31mB3......' \
--data-urlencode 'grant_type=refresh_token' \
--data-urlencode 'client_secret=45Y8Q~Xw4Pj3GN65J.......'

Solution

  • This won't work:

    scope=f66eccc4-7397-4c3a-9999-36d2d3156788/.default
    

    You are saying to Entra ID that you want an access token targeting your API, not Graph API.

    You need to use this to get a Graph API token:

    scope=https://graph.microsoft.com/.default
    

    This assumes you have setup the needed permissions in API permissions tab of the app registration.