update EWS connection code from basic authentication to use OAUTH 2.0 in c#

Viewed 324

I'm new too c#. I'm trying to update the exchange connection code to use OAuth 2.0 instead of basic authentication.

this is my existing code I have to convert:

ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2013_SP1);
service.Url = new Uri(https://outlook.office365.com/EWS/Exchange.asmx);
service.Credentials = new NetworkCredential("USER", "PASSWORD");
service.HttpHeaders.Add("X-AnchorMailbox", "USER);
service.AutodiscoverUrl(emailProcesses.AccountName, RedirectionUrlValidationCallback);

I have registered the app in azure ad. How to proceed? Should I proceed with Graph API or EWS managed Api?

1 Answers

If you want to use the OAUTH 2.0 authentication for EWS then you need to acquire an access token and use it with every request. Instead of the network credentials you will use the OAuthCredentials class.

 service.Credentials = new OAuthCredentials(authResult.AccessToken);

First the access token needs to be acquired interactively, meaning that a user needs to sign in using a popup window or browser, depending on your use case. After that with every EWS request you will renew this token using the refresh token

You can use the following logic for acquiring the access token:

AuthenticationResult authResult = null;

        IPublicClientApplication publicApp = PublicClientApplicationBuilder.Create(clientID)
                        .WithAuthority($"{instance}{tenantId}")
                        .WithDefaultRedirectUri()
                        .Build();
        TokenCacheHelper.GetInstance().EnableSerialization(publicApp.UserTokenCache);

        var accounts = publicApp.GetAccountsAsync().Result;
        var firstAccount = accounts.FirstOrDefault();

        try
        {
            //first try to silently get the token
            authResult = publicApp.AcquireTokenSilent(scopes, firstAccount)
                .ExecuteAsync().Result;
            TraceWriter.Write(typeof(EwsProxyFactory), "InitializeToken", "The authentication token was acquired silently. Expiration time: " + authResult.ExpiresOn.DateTime.ToString());
        }

        catch (MsalUiRequiredException ex)
        {
            // A MsalUiRequiredException happened on AcquireTokenSilent, meaning that the token couldn't be acquired silently
            TraceWriter.Write(typeof(EwsProxyFactory), "InitializeToken", "Failed to acquire the authentication token silently. The user needs to authenticate itself.");
           
            //todo: create custom exception 
            throw new UnauthorizedAccessException("Token expired but running in silent mode");
        }
        catch (Exception ex)
        {
            TraceWriter.Write(typeof(EwsProxyFactory), "InitializeToken", "Error Acquiring Token Silently: " + ex);
            throw;
        }

for more info read here: https://docs.microsoft.com/en-us/azure/active-directory/develop/scenario-spa-acquire-token?tabs=javascript2

Related