Office365 + OAuth2: EWSClient.GetClient results in Exception

Hi,

I’m trying to migrate from basic authentication to OAuth2 authentication to read email from different users from Office 365, as basic authentication will be deprecated in October.

This is the code (which is pretty straightforward):

static void Run()
{
    new Aspose.Email.License()
        .SetLicense("Aspose.Total.lic");

    var scopes = new string[]
    {
        "https://outlook.office.com/.default"
    };

    var app = ConfidentialClientApplicationBuilder
        .Create(CLIENT_ID)
        .WithAuthority(AzureCloudInstance.AzurePublic, TENANT_ID)
        .WithClientSecret(SECRET)
        .Build();

    var tokenProvider = new TokenProvider(app, scopes);

    var credentials = new OAuthNetworkCredential(tokenProvider);

    var client = EWSClient.GetEWSClient(
        "https://outlook.office365.com/EWS/Exchange.asmx",
        credentials);
}
public class TokenProvider : ITokenProvider
{
    private readonly IConfidentialClientApplication _App;
    private readonly string[] _Scopes;

    public TokenProvider(IConfidentialClientApplication app, params string[] scopes)
    {
        _App = app;
        _Scopes = scopes;
    }

    public OAuthToken GetAccessToken()
    {
        return GetOAuthToken();
    }
    public OAuthToken GetAccessToken(bool ignoreExistingToken)
    {
        return GetOAuthToken();
    }

    private OAuthToken GetOAuthToken()
    {
        var token = _App
            .AcquireTokenForClient(_Scopes)
            .ExecuteAsync()
            .Result;

        return new OAuthToken(
            token.AccessToken,
            TokenType.AccessToken,
            token.ExpiresOn.DateTime);
    }

    public void Dispose()
    {
    }
}

When executing this code it results in an exception: “ExchangeImpersonation SOAP header must be present for this type of OAuth token.”.

Using Microsoft.Exchange.WebServices.Data.ExchangeService I’m able to access user mailboxes by applying an ImpersonatedUserId:

var client = new ExchangeService();
client.Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx");
client.Credentials = new OAuthCredentials(tokenProvider.GetAccessToken().Token);
client.ImpersonatedUserId = new ImpersonatedUserId(
    ConnectingIdType.SmtpAddress,
    user);

client.HttpHeaders.Add("X-AnchorMailbox", user);

var folders = client.FindFolders(WellKnownFolderName.MsgFolderRoot, new FolderView(int.MaxValue));

As of this the problem is not related to the access token but to EWSClient. Could you please take a look whether I add something to my code or whether you have to update something?

I’ve already read https://forum.aspose.com/t/oauth2-support-for-o365/205188, but this is not a solution!

Regards, Stefan

@stefan.heim

I suggest you to please visit the following thread for your convenience.

OK, an overload for adding the ImpersonatedUserId should resolve my problem.
Do you have any timeframe as when this will be added? We need to finalize our development and testing as of the changes Microsoft is doing in authorization in Office 365 in October.

@stefan.heim

In order to perform impersonation you have to invoke method IEWSClient.ImpersonateUser using latest Aspose.Email for .NET 20.8.

The error with “ExchangeImpersoation SOAP header must be present for this type of OAuth token” occurs when calling EWSClient.GetEWSClient. As of this I don’t have an EWSClient to call ImpersonateUser …

@stefan.heim

Can you please share the details of issue on your end.in the form of sample project.

Sure, please take a look at the attached sample. TestOffice365.zip (109.5 KB) The app should read the inbox of different users and save all messages to file storage.

In Azure i’ve registered an app with the following permissions:
image.png (43.2 KB)

plus configured the enterprise app with the following:
image.png (53.7 KB)

And this is the exception:
image.png (9.2 KB)

If it’s easier for you I can provide you an “TENANT_ID”, “CLIENT_ID” and “SECRET”. In this case please tell me where to send these data in private.

@stefan.heim

I have opened a ticket with ID EMAILNET-39922 in our issue tracking system to further investigate this on our end. For your following comments, please share the information using Private Message option with me so that I may append the information in our issue tracking system too. You can click on my name icon in my post and will see option Message in popup. Use that to send privately.

Hi,

any updates on this?

We’re only 3 weeks away from Microsoft disabling basic auth and we really should implement this on our side too. If we don’t get a solution from your side, we have to change to another product which will result in not renewing our license, as Aspose.Email is the most important library in your suite for us.

@stefan.heim

We are hopeful that the fix for this issue will likely be shared in upcoming Aspose.Email for .NET 20.9. We request for your patience and will update you as soon as it will be fixed.

Hi,

I’ve seen that you closed the internal ticket and published 20.9.0. Can you please tell me what I’ve to do now to get my sample-project working?

OAuthNetworkCredentials has now a “userName”. When using the email-address of the mailbox, I would like to access, as this user it works!

Thanks!

@stefan.heim

It’s good to know that new changes in API have proved to be working on your end.

The issues you have found earlier (filed as EMAILNET-39922) have been fixed in this update.