OAuth 2.0 password grant with Office365/Exchange IMAP/POP3/SMTP

This article shows how to implement OAuth 2.0 password grant flow to access Office365 via IMAP, POP3 or SMTP using Mail.dll .NET email client.

Enable email protocols

Make sure IMAP/POP3/SMTP is enabled for your organization and mailbox:
Enable IMAP/POP3/SMTP in Office 365

Disable MFA for account

Password grant flow requires Multi-Factor Authentication (MFA) to be disabled for this mailbox – make also sure there are no Active Directory policies that match this account and require MFA (you can of course have policies that match all other accounts).

Go to Microsoft365 admin center. Select Setup on the left menu and in the Sign-in and security section select Configure multifactor authentication (MFA):

You can use per-user MFA or AD policies.

Register and configure application

Register your application in Azure Portal, here’s a detailed guide how to do that:
https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app

Enable additional flows:

Then you need to apply correct API permissions and grant the admin consent for your domain.

In the API permissions / Add a permission wizard, select Microsoft Graph and then Delegated permissions to find the following permission scopes listed:

  • offline_access
  • email
  • IMAP.AccessAsUser.All
  • POP.AccessAsUser.All
  • SMTP.Send

Remember to Grant admin consent:

Obtain OAuth 2.0 token

Use Microsoft Authentication Library for .NET (MSAL.NET) nuget package to obtain an access token:
https://www.nuget.org/packages/Microsoft.Identity.Client/

string clientId = "Application (client) ID";
string tenantId = "Directory (tenant) ID";

string userEmail = "Username for mailbox";
string userPassword = "Password for that user";

IPublicClientApplication app = PublicClientApplicationBuilder
    .Create(clientId)
    .WithTenantId(tenantId)
    .Build();

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

Now acquire an access token and a user name:

string userName;
string accessToken;

var account = (await app.GetAccountsAsync()).FirstOrDefault();

try
{
    AuthenticationResult refresh = await app
        .AcquireTokenSilent(scopes, account)
        .ExecuteAsync();

    userName = refresh.Account.Username;
    accessToken = refresh.AccessToken;
}
catch (MsalUiRequiredException e)
{
    SecureString securePassword = new SecureString();
    foreach (char c in userPassword)
    {
        securePassword.AppendChar(c);
    }

    var result = await app.AcquireTokenByUsernamePassword(
        scopes, 
        userEmail, 
        securePassword).ExecuteAsync();

    userName = result.Account.Username;
    accessToken = result.AccessToken;
}

Install Mail.dll email library

The easiest way to install Mail.dll is to download it from nuget via Package Manager:

PM> Install-Package Mail.dll

Alternatively you can download Mail.dll directly from our website.

Download and process emails

Finally you can connect using IMAP/POP3/SMTP, authenticate and download user’s emails:

using (Imap client = new Imap())
{
    client.ConnectSSL("outlook.office365.com");
    client.LoginOAUTH2(userName, accessToken);
 
    client.SelectInbox();

    List<long> uids = imap.Search(Flag.Unseen);
    foreach (long uid in uids)
    {
        IMail email = new MailBuilder()
                .CreateFromEml(imap.GetMessageByUID(uid));
        string subject = email.Subject;
   }

    client.Close();
} 


Get Mail.dll

Tags:     

Questions?

Consider using our Q&A forum for asking questions.