Office 365 and IMAP or POP3 with OAuth 2.0 authentication in unattended (app-only) mode: How to make it work
On October 1st 2022, Microsoft will begin disabling Basic authentication in Microsoft 365 for IMAP, POP3 and EWS. This means that classic username/password authentication will no longer work with Exchange Online, and application will have to be upgraded to use OAuth 2.0.
Microsoft 365 (formerly Office 365) supports two kinds of OAuth 2.0 authentication:
Delegated authentication is suitable for desktop, mobile or web applications with signed-in user present.
This mode is described in detail in another article.App-only authentication is suitable for services or daemons with no user present. Instead, these unattended applications authenticate using client secrets (application credentials) to receive an access token, which is then used to gain access to a mailbox using IMAP, POP3 or EWS protocols.
Before your application can start accessing mailboxes, you have to register it with Microsoft, assign the relevant permissions and configure mailbox access. The guide below describes what needs to be done to enable POP3 or IMAP access for unattended apps (app-only mode). For EWS, see Office 365 and EWS with OAuth 2.0 in unattended mode.
Table of contents
Register yourself and your company
Log into Azure Portal. If you don't have an account there yet, create it. You also have to set up a tenant that represents your company.
If you administer more than one tenant, use
Directories + subscriptions
filter to select the tenant for whom to register an application.
Register your application
In Azure Portal ⇒ expand the left menu ⇒ select
Azure Active Directory
⇒ selectApp registrations
⇒ click+ New registration
. (Azure Portal is constantly evolving, so if you cannot find this page, use the search bar.)Name your application, choose which kind of accounts are going to use it, and click
Register
.Note: This guide is suitable for single tenant account types. For other types, further steps might be different.
You successfully registered your application and you can view its associated IDs. Some of them will be needed later to obtain an OAuth 2.0 token.
Set up client secret (application password)
In the left menu, select
Certificates & secrets
⇒ click+ New client secret
.Provide some description for this secret, choose expiration period, and click
Add
.Immediately copy and save the newly created client secret's
Value
(notSecret ID
). You will not be able to view theValue
later anymore.
Add app permissions
In the left menu, select
API permissions
⇒ click+ Add a permission
.Navigate to
APIs my organization uses
tab ⇒ typeOffice 365 Exchange
in the search bar ⇒ clickOffice 365 Exchange Online
entry.Click
Application permissions
⇒ typeAccessAsApp
⇒ checkIMAP.AccessAsApp
and/orPOP.AccessAsApp
⇒ clickAdd permissions
.The newly-added
IMAP.AccessAsApp
andPOP.AccessAsApp
permissions have to be approved by your organization's administrator. Ask them to grant consent to your application by clickingGrant admin consent for [organization]
.Application permissions have been granted. Optionally, you can remove the delegated
User.Read
permission which is not needed for app-only application - click the context menu on the right side of the permission and selectRemove permission
.
Add mailbox access permissions
Now, you have to assign access permissions for your mailboxes. There is no web UI for this yet - you have to use PowerShell.
Install the required PowerShell modules.
You can skip this step if you have already installed
AzureAD
andExchangeOnlineManagement
modules.Open your PowerShell as Administrator, and run:
Install-Module -Name AzureAD Install-Module -Name ExchangeOnlineManagement
Confirm installation from
PSGallery
by typingY
+Enter
.(Wondering why these modules install from an untrusted repository? See this answer to Azure-PowerShell issue.)
Get the service principal ID associated with your application.
Note: You will be asked to log into your Azure account.
$AppId = "YOUR_APP_ID_HERE" $TenantId = "YOUR_TENANT_ID_HERE" Import-module AzureAD Connect-AzureAd -Tenant $TenantId ($Principal = Get-AzureADServicePrincipal -filter "AppId eq '$AppId'") $PrincipalId = $Principal.ObjectId
Register the service principal for your application.
Note: You will be asked to log into your Exchange Online account.
$DisplayName = "Some principal name for IMAP/POP3 here" Import-module ExchangeOnlineManagement Connect-ExchangeOnline -Organization $TenantId New-ServicePrincipal -AppId $AppId -ServiceId $PrincipalId -DisplayName $DisplayName
Add
FullAccess
mailbox permissions to all mailboxes you want to access from your application.Add-MailboxPermission -User $PrincipalId -AccessRights FullAccess -Identity "mailbox.1@example.org" Add-MailboxPermission -User $PrincipalId -AccessRights FullAccess -Identity "mailbox.2@example.org" Add-MailboxPermission -User $PrincipalId -AccessRights FullAccess -Identity "mailbox.3@example.org"
Congratulations! Now you have registered an application for accessing Office 365 mailboxes via IMAP or POP3 protocol and received its
Application (client) ID
,Client secret
andDirectory (tenant) ID
.These strings are going to be used by your application to authenticate to Microsoft 365 via OAuth 2.0 and receive an OAuth token. This token is then used to authenticate to Exchange Online using IMAP or POP3 protocols.
Let's write some code!
In your application, add reference to Microsoft.Identity.Client package, and specify your IDs, the secret, and the e-mail address. Specify the scope to request a token as well (use
https://outlook.office365.com/.default
for app-only mode).// application (client) ID obtained from Azure const string ClientId = "4f5a9f88-1111-1111-1111-bdca9a88c089"; // change to your AppId // application's 'client secret' value (application password) const string ClientSecretValue = "ThisIsSomeVerySecretValue"; // change to your secret value // your organization's directory (tenant) ID const string TenantId = "fb561382-2222-2222-2222-06ab992d36b7"; // change to your TenantId // mailbox to access (not an alias) const string SmtpAddress = "someone@example.org"; // change this // default scope of permissions to request static readonly string[] Scopes = new[] { "https://outlook.office365.com/.default", // for accessing Exchange Online with app-only auth };
Before your application connects to Office 365's IMAP or POP3 service, it has to request an OAuth 2.0 access token using the Microsoft's authentication API.
using Microsoft.Identity.Client; ... // get an instance of 'confidential client application' API var cca = ConfidentialClientApplicationBuilder .Create(ClientId) .WithClientSecret(ClientSecretValue) .WithTenantId(TenantId) .Build(); // acquire OAuth 2.0 access token from Microsoft 365 AuthenticationResult result = await cca.AcquireTokenForClient(Scopes).ExecuteAsync(); string accessToken = result.AccessToken;
Then, connect to
outlook.office365.com
using Rebex IMAP or Rebex POP3 package and use the acquired token to start accessing your organization's mailboxes.using Rebex.Net; ... // connect to Office 365 and authenticate using access token var client = new Imap(); // or new Pop3() client.Connect("outlook.office365.com", SslMode.Implicit); client.Login(SmtpAddress, accessToken, ImapAuthentication.OAuth20); // start working with the mailbox ...
To give this a try before adding the code to your application, try our ImapOAuthAppOnlyConsole or Pop3OAuthAppOnlyConsole samples.
Documentation for IMAP and POP3 .NET libraries
- Rebex Mail Pack homepage
- Rebex Mail Pack download
- IMAP message operations
- IMAP folder operations
- IMAP searching
- POP3 operations
Any issues?
Make sure you used correct IDs in PowerShell cmdlets. If the IDs are mismatched, your app will be able to request an access token, but won't be able to use it to access mailboxes.
Use an up-to-date version of Rebex IMAP, Rebex POP3 or Rebex Mail Pack. Old versions of Mail Pack have not been tested with contemporary Exchange Online. They might still work, but if you encounter any issues, please try the latest release.
This guide is only suitable for IMAP and POP3. For Exchange Web Services guide, see Office 365 and EWS with OAuth 2.0.
Microsoft 365 does not support app-only authentication for SMTP yet. However, it will still be possible to enable username/password authentication for SMTP after October 1st 2022.
Need help? Ask at Rebex Q&A Forum.