OAuth 2.0 with Office365/Exchange IMAP/POP3/SMTP
OAuth 2.0 web flow with Office365/Exchange IMAP/POP3/SMTP
OAuth 2.0 password grant with Office365/Exchange IMAP/POP3/SMTP
OAuth 2.0 device flow with Office365/Exchange IMAP/POP3/SMTP
OAuth 2.0 client credential flow with Office365/Exchange IMAP/POP3/SMTP
Note: If you still get an
error running the New-ServicePrincipal
cmdlet after you perform these steps, it is likely due to the fact that
the
user doesn’t have enough permissions in Exchange online
to perform the operation. By default this cmdlet is available to users assigned the
Role Management
role
Add permissions
to a specific mailbox:
Add-MailboxPermission
-Identity "<USER@your-domain.onmicrosoft.com>"
-User <OBJECT_ID>
-AccessRights FullAccess
In our case:
Add-MailboxPermission
-Identity "AdeleV@your-domain.onmicrosoft.com"
-User 4352fc11-5c2f-4b0b-af40-447ff10664e8
-AccessRights FullAccess
string clientId = "Application (client) ID"; // 061851f7-...
string tenantId = "Directory (tenant) ID";
string clientSecret = "Client secret value";
string userName = "Username/email for mailbox"; // AdeleV@...
var app = ConfidentialClientApplicationBuilder
.Create(clientId)
.WithTenantId(tenantId)
.WithClientSecret(clientSecret)
.Build();
string[] scopes = new string[] {
"https://outlook.office365.com/.default"
' VB.NET
Dim clientId As String = "Application (client) ID" ' 061851f7-...
Dim tenantId As String = "Directory (tenant) ID"
Dim clientSecret As String = "Client secret value"
Dim userName As String = "Username/email for mailbox" 'AdeleV@...
Dim app = ConfidentialClientApplicationBuilder.Create(clientId) _
.WithTenantId(tenantId) _
.WithClientSecret(clientSecret) _
.Build()
Dim scopes As String() = New String() { _
"https://outlook.office365.com/.default" _
Now acquire an access token:
// C#
var result = await app.AcquireTokenForClient(scopes)
.ExecuteAsync();
string accessToken = result.AccessToken;
' VB.NET
Dim result = Await app.AcquireTokenForClient(scopes).ExecuteAsync()
Dim accessToken As String = result.AccessToken
Finally you can connect using IMAP/POP3, authenticate and download user’s emails:
// C#
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();
' VB.NET
Using client As Imap = New Imap()
client.ConnectSSL("outlook.office365.com")
client.LoginOAUTH2(userName, accessToken)
client.SelectInbox()
Dim uids As List(Of Long) = imap.Search(Flag.Unseen)
For Each uid As Long In uids
Dim email As IMail = New MailBuilder() _
.CreateFromEml(imap.GetMessageByUID(uid))
Dim subject As String = email.Subject
client.Close()
End Using
Currently Microsoft doesn’t support
client credential
flow + SMTP.
For this flow only POP3 and IMAP permissions are available:
POP.AccessAsApp
for POP3 client access and
IMAP.AccessAsApp
for IMAP client access
All other OAuth flows (
web
,
desktop
,
password grant
,
device
) support SMTP client access.
“
SMTP AUTH will still be available
when Basic authentication is permanently disabled on October 1, 2022.” (
https://docs.microsoft.com/en-us/exchange/clients-and-mobile-in-exchange-online/deprecation-of-basic-authentication-exchange-online
)
However Microsoft disables SMTP AUTH in all tenants in which it’s not being used.
Here’s how to
enable SMTP AUTH
:
https://learn.microsoft.com/en-us/exchange/clients-and-mobile-in-exchange-online/authenticated-client-smtp-submission
Troubleshooting
1. Start with
PowerShell
commands:
Get-ServicePrincipal
Get-MailboxPermission -Identity "AdeleV@your-domain.onmicrosoft.com"
You should see following results:
https://docs.microsoft.com/en-us/powershell/exchange/exchange-online-powershell-v2?view=exchange-ps#install-and-maintain-the-exo-v2-module
https://docs.microsoft.com/en-us/exchange/client-developer/legacy-protocols/how-to-authenticate-an-imap-pop-smtp-application-by-using-oauth#use-client-credentials-grant-flow-to-authenticate-imap-and-pop-connections