Search code examples
c#impersonationexchangewebservices

How to use EWS on hosted Exchange with Impersonation?


I want to create a service which to crawl all inboxes of all users on a hosted exchange server (“myclient.onmicrosoft.com”) via EWS.

This already works well when I connect to on-premise exchange servers in the same domain. But when I try to connect this service to a hosted exchange, it throws 401 (wrong authorization) errors. Of course, this is a different domain as the hosted exchange server. My service runs on an on-premise server and uses a “god-mode” user to impersonalise to all active directory users. My question is: How to connect the users of my on-premise system correctly to the hosted exchange in a different domain?

Note: It works when I use the credentials directly and the impersonation way does work on on-premise installations.

What I did so far (and I wonder of this is the right way to do it): On our on-premise server I created a domain “myclient.onmicrosoft.com” just like on the hosted server and an AD user with the same name and password as on the hosted exchange (called “[email protected]”).

On my crawler service I did:

  1. I got all AD users in our on premise server

    var allUsers = SearchAllActiveDirectoryUsers();
    
          foreach (DataRow user in allUsers.Rows)
          {
                    String domainName = (String)user["DomainName"];
                    String samAccountName = (String)user["SamAccountName"];
                    String principalName = (String)user["PrincipalName"];
                    String principalDomainName = (String)user["PrincipalDomainName"];
                    String mail = (String)user["Mail"];
            }
    
  2. Then for each AD user I connected the user with the exchange service like this:

    ExchangeService ex = new ExchangeService(version);
        ex.Url = new Uri(“https://outlook.office365.com/EWS/Exchange.asmx”);
        ex.Credentials = new WebCredentials("[email protected]", “XXX”, " myclient.onmicrosoft.com"); 
        // THIS DOES WORK CORRECTLY!
        ex.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.PrincipalName, “[email protected]”);
        //this does NOT work!
    

Any ideas what I am missing?


Solution

  • You need to use the credentials of your "god-mode" user, but set the ImpersonatedUserId to the AD user. Something like:

    ex.Credentials = new WebCredentials("[email protected]", "password");
    ex.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.PrincipalName, "[email protected]");
    

    When you connect to Office 365 via EWS, you always need to supply credentials. You can't use UseDefaultCredentials = true.