calendarexchangewebservicesews-managed-api

EWS API calendar - Impersonating to update raise an error "Access is denied. Check credentials and try again."


I am new to using EWS managed APIs.

Following is the issue I am facing with EWS APIs: EWS API - Impersonating to update a calendar item created by any other user than a service account, raise an error "Access is denied. Check credentials and try again."

Details: 1. I am using a service account e.g. abc@xyz.onmicrosoft.com. This user is a global administrator and also has ApplicationImpersonation role assigned. (Sign into Online Office 365 account -> Admin -> select "Exchange" tab- > select Permissions on the left panel -> create an impersonation role -> assign ApplicationImpersonation in Roles: and abc@xyz.onmicrosoft.com in Members: -> Click on save)

  1. Create a calendar item by other user for e.g. pqr@xyz.onmicrosoft.com, and invite an attendee - abc@xyz.onmicrosoft.com.

  2. In a c# program, I connect to EWS service using a service account - abc@xyz.onmicrosoft.com, fetch its calendar events. If organizer of an event is some other user - pqr@xyz.onmicrosoft.com then I use impersonation in the following way to update the calendar event/item properties- subject, body text etc.

    private static void Impersonate(string organizer)
    {
        string impersonatedUserSMTPAddress = organizer;
        ImpersonatedUserId impersonatedUserId =
            new ImpersonatedUserId(ConnectingIdType.SmtpAddress, impersonatedUserSMTPAddress);
    
        service.ImpersonatedUserId = impersonatedUserId;
    }
    
  3. It was working fine till yesterday afternoon. Suddenly, it started throwing an exception "Access is denied. Check credentials and try again." Whenever I try to update that event.

    private static void FindAndUpdate(ExchangeService service) { CalendarView cv = new CalendarView(DateTime.Now, DateTime.Now.AddDays(30)); cv.MaxItemsReturned = 25; try { FindItemsResults masterResults = service.FindItems(WellKnownFolderName.Calendar, cv);

            foreach (Appointment item in masterResults.Items)
            {
                if (item is Appointment)
                {
                    Appointment masterItem = item as Appointment;
                    if (!masterRecurEventIDs.Contains(masterItem.ICalUid.ToString()))
                    {
                        masterItem.Load();
    
                        if (!masterItem.Subject.Contains(" (Updated content)"))
                        {
                            //impersonate organizer to update and save for further use
                            Impersonate(masterItem.Organizer.Address.ToString());
    
                            // Update the subject and body
                            masterItem.Subject = masterItem.Subject + " (Updated content)";
    
                            string currentBodyType = masterItem.Body.BodyType.ToString();
                            masterItem.Body = masterItem.Body.Text + "\nUpdated Body Info: xxxxxxxxxxxx";
    
                            // This results in an UpdateItem operation call to EWS.
                            masterItem.Update(ConflictResolutionMode.AutoResolve);
    
                            // Send updated notification to organizer of an appointment
                            CreateAndSendEmail(masterItem.Organizer.Address.ToString(), masterItem.Subject);
    
                            masterRecurEventIDs.Add(masterItem.ICalUid.ToString());
                        }
                        else
                        {
                            Console.WriteLine("Event is already updated. No need to update again.:\r\n");
                            Console.WriteLine("Subject: " + masterItem.Subject);
                            Console.WriteLine("Description: " + masterItem.Body.Text);
                        }
                    }
    
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("Error: " + ex.Message);
        }
    }
    
  4. What could be an issue here? Initially I thought may be its a throttling policy which is stopping same user after making certain API call limits for the day, but I am still seeing this issue today.

Any help is appreciated.

Thanks


Solution

  • Found the solution:

    Only adding impersonated ID to the existing service instance doesn't work. You also need to re-validate the auto-discover url.