php-ews icon indicating copy to clipboard operation
php-ews copied to clipboard

ExchangeImpersonation SOAP header must not exist for this type of OAuth token.

Open sritechie26 opened this issue 6 years ago • 11 comments

Version (e.g. 1.0, dev-master): PHP version: 5.6.25 Microsoft Exchange version: Office 365

Description of problem: It was working fine on Exchange server 2007 and 2010, also on office 365 as well. but from last couple of days its throwing some error while creating calendar entry by impersonating on office 365.

The error read as "ExchangeImpersonation SOAP header must not exist for this type of OAuth token." It was working well earlier, Anyone faced this issue recently? any pointers to solve this issue please? Example request:

//creating the CALENDAR event
function createCalendarEvent($params){

	$ews = ews_initialisation();

	if(empty($params['assigneeEmail']))
	{
		return true;
	}
	if(empty($params['details']) || $params['details'] =='' || $params['details'] == 'null')
	{
		$params['details'] = 'No Details';
	}
		$ews = ews_initialisation();

	// Impersonating the user
	$ei = new EWSType_ExchangeImpersonationType();
	$sid = new EWSType_ConnectingSIDType();
	$sid->PrimarySmtpAddress = $params['assigneeEmail'];
	$ei->ConnectingSID = $sid;
	$ews->setImpersonation($ei);
	
	// Start building the request.
	$request                                                  = new EWSType_CreateItemType();
	$request->Items                                           = new EWSType_NonEmptyArrayOfAllItemsType();
	$request->Items->CalendarItem                             = new EWSType_CalendarItemType();
	// Set the subject.
	$request->Items->CalendarItem->Subject                    = $params['subject'];//$subject;
	// Set the start and end times. For Exchange 2007, you need to include the timezone offset.

	$request->Items->CalendarItem->Start                      = $params['newTime'];//$date->format('c');
	$request->Items->CalendarItem->End                        = $params['endTime'];//$date->format('c');
	// Set no reminders
	$request->Items->CalendarItem->ReminderIsSet              = false;
	// Or use this to specify when reminder is displayed (if this is not set, the default is 15 minutes)
	$request->Items->CalendarItem->ReminderMinutesBeforeStart = 15;
	// Build the body.
	$request->Items->CalendarItem->Body                       = new EWSType_BodyType();
	$request->Items->CalendarItem->Body->BodyType             = EWSType_BodyTypeType::HTML;
	
	$attendees = array($params['assigneeEmail']);
	$attendants = implode(',',$attendees);
	$request->Items->CalendarItem->Body->_                    = <<<EOD

    <p><strong></strong>{$params['details']}</p>
		
EOD;

	// Set the item class type (not required).
	$request->Items->CalendarItem->ItemClass                                             = new EWSType_ItemClassType();
	$request->Items->CalendarItem->ItemClass->_                                          = EWSType_ItemClassType::APPOINTMENT;
	// Set the sensativity of the event (defaults to normal).
	$request->Items->CalendarItem->Sensitivity                                           = new EWSType_SensitivityChoicesType();
	$request->Items->CalendarItem->Sensitivity->_                                        = EWSType_SensitivityChoicesType::NORMAL;
	// Add some categories to the event.
	$request->Items->CalendarItem->Categories                                            = new EWSType_ArrayOfStringsType();
	$request->Items->CalendarItem->Categories->String                                    = array(
			'Client Meeting (Scheduled)'
	);
	// Set the importance of the event.
	// $request->Items->CalendarItem->Importance = new EWSType_ImportanceChoicesType();

	// $request->Items->CalendarItem->Importance->_ = EWSType_ImportanceChoicesType::NORMAL;
	$request->Items->CalendarItem->Location                                              = $params['location'];
	
	// Send meeting invitations.
	$request->SendMeetingInvitations                                                     = EWSType_CalendarItemCreateOrDeleteOperationType::SEND_ONLY_TO_ALL;
  $response      = $ews->CreateItem($request);	
	
	return $response;

	
}


function ews_initialisation(){
	spl_autoload_register('classAutoLoader');

	//outlook 365 login details
	$server = 'outlook.com';
	$username = '[email protected]';
	$password = 'xxxxxxxxxx';
	
	
	
	$ews = new ExchangeWebServices($server, $username, $password, $version);
	return $ews;
}

Example response:

Fatal Error Details = Array
(
    [message] => ExchangeImpersonation SOAP header must not exist for this type of OAuth token.
    [code] => 
    [exception] => SoapFault Object
        (
            [message:protected] => ExchangeImpersonation SOAP header must not exist for this type of OAuth token.
            [string:Exception:private] => 
            [code:protected] => 0
            [file:protected] => mysite/extensions/exchange_server_integration/ExchangeWebServices.php
            [line:protected] => 332
            [trace:Exception:private] => Array
                (
                    [0] => Array
                        (
                            [file] => mysite/extensions/exchange_server_integration/ExchangeWebServices.php
                            [line] => 332
                            [function] => __call
                            [class] => SoapClient
                            [type] => ->
                            [args] => Array
                                (
                                    [0] => CreateItem
                                    [1] => Array
                                        (
                                            [0] => EWSType_CreateItemType Object
                                                (
                                                    [Items] => EWSType_NonEmptyArrayOfAllItemsType Object
                                                        (
                                                            [AcceptItem] => 
                                                            [AcceptSharingInvitation] => 
                                                            [CalendarItem] => EWSType_CalendarItemType Object
                                                                (
                                                                    [AdjacentMeetingCount] => 
                                                              

sritechie26 avatar Aug 29 '18 11:08 sritechie26

@sritechie26 I'm seeing this today. Did you find the cause?

nkew avatar Sep 03 '18 14:09 nkew

@sritechie26 @nkew same here today. Might be related to this: https://blogs.technet.microsoft.com/exchange/2018/07/03/upcoming-changes-to-exchange-web-services-ews-api-for-office-365/

Guess we should be migrating our apps to Graph soon.

denndk avatar Sep 04 '18 08:09 denndk

@sritechie26 @denndk Adding the following headers fixed this issue for me:

X-AnchorMailbox": emailAddress
X-PreferServerAffinity": "true"

nkew avatar Sep 04 '18 13:09 nkew

@nkew where did you add it and how?

denndk avatar Sep 04 '18 13:09 denndk

To answer my own question, this did the trick for me: `

    $client = new Client($host, $username, $password, $version);
    $headers = array(
        'X-AnchorMailbox: ' . $mailbox . '',
        'X-PreferServerAffinity: true');
    $client->setCurlOptions(
        array(CURLOPT_HTTPHEADER => $headers)
   );

`

denndk avatar Sep 05 '18 09:09 denndk

@denndk Glad you got it resolved!

nkew avatar Sep 05 '18 09:09 nkew

@denndk @nkew Glad that you guys found the solution. In My case I did not make any change but it started working fine a day later. It sounds silly but I did not make any change in the code.

Network administrator who handles office 365 said that they did not make any change either. but they raised the ticket with Microsoft support team.

I have no idea how its got fixed.

sritechie26 avatar Sep 05 '18 11:09 sritechie26

@sritechie26 If i use my old code the issue still persists (sometimes). However I changed part of my code to Microsoft Graph and here I also have to specify the X-AnchorMailbox header. So nevertheless is should been implemented, when impersonating a user. Could be included in the setImpersonation() function.

I also searched from any recent updates to their services, but could not find any information either.

denndk avatar Sep 05 '18 11:09 denndk

@sritechie26 did you get a respond from the microsoft support team? I am experiencing inconsistent responses. Sometimes the Response Message contains an array, sometimes not. I am handling this behaviour in my code, but I would like to know the root cause.

denndk avatar Sep 13 '18 11:09 denndk

@nkew @denndk Thanks to you both, I managed to backport the fix to the very old release of PHP-EWS (0.1) I am stuck with. Thanks!

gdementen avatar Nov 28 '18 10:11 gdementen

Coming back to this in 2019... I've just upgraded from Exchange 2016 to Exchange 2019. I was having similar issues at the top of the page, so tried @denndk 's solution.

Unfortunately this seems to overwrite the default headers that PHP-EWS sends rather than adding them as additional headers.

I took a look into the soap-ntlm code and reconstructed the headers to look like this:

$headers = array(
        'X-AnchorMailbox: ' . $mailbox . '',
        'X-PreferServerAffinity: true',
	'Method: POST',
	'Connection: Keep-Alive',
	'User-Agent: PHP-SOAP-CURL',
	'Content-Type: text/xml; charset=utf-8',
	'Expect: 100-continue',
);

This then allowed the code to work.

For Google to index... I was getting this error without this modification:

Uncaught Exception: SOAP client returned status of 415.

davehamer avatar May 15 '19 07:05 davehamer