1
votes

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. [email protected]. 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 [email protected] in Members: -> Click on save)

  1. Create a calendar item by other user for e.g. [email protected], and invite an attendee - [email protected].

  2. In a c# program, I connect to EWS service using a service account - [email protected], fetch its calendar events. If organizer of an event is some other user - [email protected] 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

2

2 Answers

0
votes

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.

0
votes

I was investigating an Impersonation + Calendar issue, and found this forum post.

I am sure your problem lies in the way you are trying to get and then update the calendar item (appointment).

You are getting the calendar item using a credentials (mailbox A). Then later on, on following line

Impersonate(masterItem.Organizer.Address.ToString());

you are instructing the Ews Service object to work as the Impersonated Identity (credentials of Mailbox B).

Since you already had grabbed the appointment from Mailbox A, and now trying to update that appointment in Mailbox A, using the credentials of Mailbox B, that should not work IMHO if Mailbox B doesn't have permission on Mailbox A calendar.

So here, actually, you are trying to update the calendar item of Mailbox A, using the impersonated credentials of Mailbox B, and as Mailbox B doesn't have permission on Mailbox A credentials, so the Access Denied error is occurring.

Hope this help someone else too. Thanks