Search code examples
outlookoffice365exchange-serverexchangewebservices

How to implement Exchange online OAuth2.0 for unmanaged EWS API?


For managed EWS code, I have used to OAuth 2.0 to get token and it worked. For unmanaged EWS, it is failing to connect to Exchange as an unauthorized error.

Below is the code to access unmanaged EWS. How to make below code work with OAuth token instead of passing credentials as below?.

Binding = new ExchangeServiceBinding
{
Url = ServerUrl,
Credentials = new OAuthCredentials(token),
RequestServerVersionValue = new RequestServerVersion { Version = ExchangeVersionType.Exchange2007_SP1 },
ExchangeImpersonation = null
};

Above is not working as credential is asking of type ICredentials and it is not accepting token. Please help me. Below is the code how I direct access managed EWS.

var authResult = await pca.AcquireTokenByUsernamePassword(ewsScopes, credential.UserName, credential.SecurePassword).ExecuteAsync();
configure the ExchangeService with the access token
ExchangeService = new ExchangeService();
ExchangeService.Url = new Uri(ServerUrl);
ExchangeService.Credentials = new OAuthCredentials(authResult.AccessToken);

Solution

  • One method i use (as I've never worked out how to override the WSDL classes) is if you modify the Reference.cs file that gets generated in the web references directory you can modify the GetWebResponse command (In this case the token is being passed via the credentials object password property but there a number of different approaches you can take here) eg

            private String AnchorMailbox;
            private bool oAuth;
    
            protected override System.Net.WebResponse GetWebResponse(System.Net.WebRequest req)
        {
            if (xAnchorMailbox != null)
            {
                if (xAnchorMailbox != "")
                {
                    req.Headers.Add("X-AnchorMailbox", AnchorMailbox);
                }
            }
            if(req.Credentials is System.Net.NetworkCredential)
            {
                if(oAuth){
                    req.Headers.Add("Authorization", ("Bearer " + ((System.Net.NetworkCredential)req.Credentials).Password));
                }
            }
    
            System.Net.HttpWebResponse
            rep = (System.Net.HttpWebResponse)base.GetWebResponse(req);
    
    
            return rep;
        }