Unable connect to the serve error when using Access Mail Services using OAuth

I read emails from an exchange online account using imap.
This worked without problem using basic authentication. Since basic authentication will be disabled by exchange online, i need to authenticate via oAuth.

I did follow the documentation on Access Mail Services using OAuth|Documentation
As described in the documentation, i’ve implemented the AzureROPCTokenProvider and configured the Exchange App Registration according to the documentation from microsoft.

The implementation AzureROPCTokenProvider seems to work and i do get a token.
image.png (50.3 KB)

This code is used for loading emails via IMAP

using (ImapClient client = new ImapClient(
“outlook.office365.com”,
993,
userName,
tokenProvider,
SecurityOptions.SSLImplicit))
{
//When this method is called, AzureROPCTokenProvider.GetAccessToken is called first
[//AzureROPCTokenProvider.GetAccessToken](https://azureropctokenprovider.getaccesstoken/) returns a valid token
//Then the exception “Unable connect to the serve” occurs
var lst = client.ListMessages();
}

The exception is “Unable connect to the server” without any further information.
Is there a way to get more useful information what exactly is not working.
Since the token can be loaded, the server seems to be available and based on the exception message it is not clear what is wrong.

Message: Unable connect to the server.
Stack Trace:    at #=z1zUrGj5sxf9uqcjTJVcVa2E7dMDr.#=zBazcka0=(IAsyncResult #=zQXkmzSo=)
   at #=z1zUrGj5sxf9uqcjTJVcVa2E7dMDr.#=zaksmQ6s=()
   at #=z_wnR4kxf0caXFBC6Gp9X7XGpTiOTg2vkkWiZUFA=.#=zFgPZw88=(#=zzdacdi9nZ_EWsncM6CvfmmlYFeXpSJT00g== #=zpgkRhnk=)
   at #=zmXwX_0NGShfKfH1ZqtD7kQ3Kx89t.#=zxJKUZtSBJVbV(Int32 #=zytvRPTU=, #=zzdacdi9nZ_EWsncM6CvfmmlYFeXpSJT00g== #=zkkiUCAA=, List`1 #=zbj3Ohq4=, Int32 #=zbK1AP4k=)
   at #=zmXwX_0NGShfKfH1ZqtD7kQ3Kx89t.#=zxJKUZtSBJVbV(Int32 #=zbK1AP4k=, #=zzdacdi9nZ_EWsncM6CvfmmlYFeXpSJT00g== #=zkkiUCAA=, #=zcmd7ccUCbZD5dS3XOwh93Os= #=zoTRekHfrrNPb, List`1 #=zbj3Ohq4=)
   at #=zmXwX_0NGShfKfH1ZqtD7kQ3Kx89t.#=zMUR_SbDdZ5go(Int32 #=zbK1AP4k=, #=zzdacdi9nZ_EWsncM6CvfmmlYFeXpSJT00g== #=zkkiUCAA=)
   at #=z1zUrGj5sxf9uqcjTJVcVa2E7dMDr.#=z$S2KR0yn2RAT()
   at #=z1zUrGj5sxf9uqcjTJVcVa2E7dMDr.#=zxCVEsC8=(AsyncCallback #=zE_F5kXw=, Object #=zW6FV2wk=)
   at Aspose.Email.Clients.Imap.ImapClient.#=zstPvzD4qxZ8L(IConnection #=zI2W9bpw=, String #=zXuPejhM=, Int64 #=z6OxiGjHloJPV, Boolean #=zs$G70cvnVz6Q, IEnumerable`1 #=zGJgsRiNqUovN, AsyncCallback #=zE_F5kXw=, Object #=zW6FV2wk=)
   at Aspose.Email.Clients.Imap.ImapClient.ListMessages()
   at PopImapOAuthAsposeDemo.Program.Main(String[] args) in C:\project\EvidenceGit\PopImapOAuthAsposeDemo\PopImapOAuthAsposeDemo\PopImapOAuthAsposeDemo\Program.cs:line 55

@azureservices.glauxs

Please read the following detail to achieve your requirement.

How To Enable or disable modern authentication

To use modern authentication, make sure that it is enabled. Modern authentication is enabled by default in Exchange Online. For tenants created before August 1, 2017, modern authentication is turned off by default.
In the Microsoft 365 admin center at https://admin.microsoft.com, go Settings > Org Settings > Modern Authentication. In the Modern authentication flyout that appears, you can identify the protocols that no longer require Basic authentication.
For new Office 365 tenants in Azure, Basic Authentication is disabled by default for all applications. In this case, the text will be displayed in this section.

Your organization has security defaults enabled, which means modern authentication to Exchange Online is required, and basic authentication connections are blocked. You must turn off security defaults in the Azure portal before you can change any settings here.

You can enable Basic Auth support for tenant from the Azure portal (Azure Active Directory → Properties → Manage Security defaults → Enable Security defaults = No ).
For more information, see the documentation on Enable or disable modern authentication for Outlook in Exchange Online | Microsoft Learn

How To use modern authentication with EwsClient

To use modern authentication with EwsClient the following is required:

  1. App registration with Azure Active Directory.
  2. Adding code to get an authentication token from a token server.
  3. Using the token to authenticate.

Note: There are two types of permissions that can be used to access EWS. Choose a specific type of permission, depending on the app you are creating:

  • Delegated permissions are used by apps that have a signed-in user present. For these apps, either the user or an administrator consents to the permissions that the app requests. In other words, when you connect to the service, a dialog window will appear to enter username and password. App can never have more privileges than the signed-in user.
  • Application permissions are used by apps that run without a signed-in user present, for example, apps that run as background services or daemons. Only an administrator can consent to application permissions.

Refer to Microsoft documentation for more information: Authenticate an EWS application by using OAuth | Microsoft Learn

App registration with Azure Active Directory

The registration procedure depends on the type of permission selected. To register your app, refer to the Microsoft documentation:

You can download full code example to use modern authentication with IMAP and SMTP clients.
EWSModernAuthenticationImapSmtp.zip (3.9 KB)

The full code example you provided appears to be private and I am unable to download it.

@tburkitt

Please download the code example from here:
EWSModernAuthenticationImapSmtp.zip (3.9 KB)

It took me some time to setup azure as described (We have an old azure tenant where modern login was not yet active)

After configuring everything as described, i still get the same exception.
image.png (40.4 KB)

Name: ImapException
Message: Unable connect to the server.
Stack Trace:    at #=z_wnR4kxf0caXFBC6Gp9X7XGpTiOTg2vkkWiZUFA=.#=zFgPZw88=(#=zzdacdi9nZ_EWsncM6CvfmmlYFeXpSJT00g== #=zpgkRhnk=)
   at #=zmXwX_0NGShfKfH1ZqtD7kQ3Kx89t.#=zxJKUZtSBJVbV(Int32 #=zytvRPTU=, #=zzdacdi9nZ_EWsncM6CvfmmlYFeXpSJT00g== #=zkkiUCAA=, List`1 #=zbj3Ohq4=, Int32 #=zbK1AP4k=)
   at #=zmXwX_0NGShfKfH1ZqtD7kQ3Kx89t.#=zxJKUZtSBJVbV(Int32 #=zbK1AP4k=, #=zzdacdi9nZ_EWsncM6CvfmmlYFeXpSJT00g== #=zkkiUCAA=, #=zcmd7ccUCbZD5dS3XOwh93Os= #=zoTRekHfrrNPb, List`1 #=zbj3Ohq4=)
   at #=zmXwX_0NGShfKfH1ZqtD7kQ3Kx89t.#=zMUR_SbDdZ5go(Int32 #=zbK1AP4k=, #=zzdacdi9nZ_EWsncM6CvfmmlYFeXpSJT00g== #=zkkiUCAA=)
   at #=z1zUrGj5sxf9uqcjTJVcVa2E7dMDr.#=z$S2KR0yn2RAT()
   at #=z1zUrGj5sxf9uqcjTJVcVa2E7dMDr.#=zxCVEsC8=(AsyncCallback #=zE_F5kXw=, Object #=zW6FV2wk=)
   at Aspose.Email.Clients.Imap.ImapClient.#=zstPvzD4qxZ8L(IConnection #=zI2W9bpw=, String #=zXuPejhM=, Int64 #=z6OxiGjHloJPV, Boolean #=zs$G70cvnVz6Q, IEnumerable`1 #=zGJgsRiNqUovN, AsyncCallback #=zE_F5kXw=, Object #=zW6FV2wk=)
   at Aspose.Email.Clients.Imap.ImapClient.ListMessages()
   at PopImapOAuthAsposeDemo.Program.<Main>d__3.MoveNext() in C:\project\EvidenceGit\PopImapOAuthAsposeDemo\PopImapOAuthAsposeDemo\PopImapOAuthAsposeDemo\Program.cs:line 135

Given is the following code

                    using (ImapClient client = new ImapClient(
                        "outlook.office365.com",
                        993,
                        userName,
                        tokenProvider,
                        SecurityOptions.Auto))
                    {
                        //When this method is called, AzureROPCTokenProvider.GetAccessToken is called first
                        //AzureROPCTokenProvider.GetAccessToken returns a valid token
                        //Then the exception "Unable connect to the serve" occurs
                        var lst = client.ListMessages();
                    }

I’ve traced the traffic using fiddler, and client.ListMessages() does make the call for the bearer token.
image.png (72.3 KB)

A bearer token is created and received, but after this, no further request is made. After 3-4 seconds, the exception Unable connect to the server occurs.

Since it can get the bearer token using the tokenprovider, it is not clear to me which server cannot be accessed and the error message doesn’t contain any additional information

I finally found the problem.

Using this scope causes the Unable connect to the server error (Aspose error, the token can be aquired).

string[] scopes = new[] { "POP.AccessAsUser.All", "SMTP.Send" };

When using this scope, mail read/send works:

string[] scopes = { "https://outlook.office.com/IMAP.AccessAsUser.All", "https://outlook.office.com/SMTP.Send" };

There might be a reason why aspose requires the url, but the error message is clearly wrong.

Side note:
Using the very same functionality does end with a timeout when using Pop3

                    //POP
                    var pop3Client = new Pop3Client(
                       "outlook.office365.com",
                       993,
                       userName,
                       tokenString.access_token, SecurityOptions.SSLAuto);
                    var lst = pop3Client.ListMessages();
                    foreach (var item in lst)
                    {
                        Console.WriteLine(item.Subject);    
                    }

There also seems to be no sample for Pop3 in EWSModernAuthenticationImapSmtp.zip
Should i create a new issue for this?

@azureservices.glauxs

It is nice to hear from you that your problem has been solved.

We have logged a ticket in tracking system as EMAILNET-40671 for this case. We will inform you via this forum thread once there is an update available on it.

@azureservices.glauxs

Please use the attached code example for Pop3Client with modern authentication.
EWSModernAuthenticationPop.zip (3.6 KB)

Please note the following points before using the code example.

  1. Use the Microsoft 365 admin center to enable or disable IMAP, POP, SMTP AUTH on specific mailboxes

    • Open the Microsoft 365 admin center and go to Users > Active users.
    • Select the user, and in the flyout that appears, click Mail.
    • In the Email apps section, click Manage email apps.
    • Verify the IMAP, POP, Authenticated SMTP setting: unchecked = disabled, checked = enabled.
    • Finally, click Save changes.
  2. Make sure to specify the full scopes, including Outlook resource URLs.

    • POP: https://outlook.office.com/POP.AccessAsUser.All
  3. The list of configured permissions should include all the permissions the application needs. pop_permission.png (17.0 KB)

  4. The encrypted port for POP3 is 995