Exchange Online POP and IMAP OAuth 2.0 Client Credentials Flow

Hi All,

OAuth 2 Authentication for POP and IMAP was announced already back in June 2022 at the Exchange Team Blog.

Announcing OAuth 2.0 Client Credentials Flow support for POP and IMAP protocols in Exchange Online
https://techcommunity.microsoft.com/t5/exchange-team-blog/announcing-oauth-2-0-client-credentials-flow-support-for-pop-and/ba-p/3562963

There is a pretty decent Step-by-step Guide here. But there are some steps missing - that's why i have created a more detailed Guide.

As a personal Opinion: I don't like this POP/IMAP approach. If you as a developer are able to change your existing Code for the Authentication and Token handling - you have already done 50% of the Job. It's easy to do the rest via Graph Calls - check out mit GitHub Repo for Examples of that https://github.com/BohrenAn/GitHub_PowerShellScripts/blob/main/ExchangeOnline/GraphAPI/ExOGraphAPI.ps1

Create the App Registration in Azure AD


Add the Permissions for the App:
Office 365 Exchange Online
- IMAP.AccessAsApp
- POP.AccessAsApp


How do you select these Permissions?
It's a little bit tricky. Instead of Microsoft Graph select the "APIs my organization uses" and search for "Office 365 Exchange Online"


Then select "Application permissions" and search for "POP" and "IMAP"


Now you need to create the Service Principal in Exchange Online. And here is another tricky part.
What do they refer to with ServiceId? It is the ObjectID of your Azure AD Application in the Enterprise Application.

New-ServicePrincipal -AppId <APPLICATION_ID> -ServiceId <OBJECT_ID> [-Organization <ORGANIZATION_ID>]


I've made that simpler with thist Microsoft Graph Call

###############################################################################
# Get AzureAD Application with Microsoft.Graph PowerShell
###############################################################################
Connect-MgGraph -Scopes 'Application.Read.All'
$ServicePrincipalDetails = Get-MgServicePrincipal -Filter "DisplayName eq 'DemoEXO-POP3-IMAP'"
$ServicePrincipalDetails



We now can create the Service Principal with the Object from the Microsoft Graph call

###############################################################################
# Create Exchange Service Principal
###############################################################################
Connect-ExchangeOnline
New-ServicePrincipal -AppId $ServicePrincipalDetails.AppId -ServiceId $ServicePrincipalDetails.Id -DisplayName "EXO Serviceprincipal $($ServicePrincipalDetails.Displayname)"



Now you need to check if POP or IMAP is enabled on the Account

###############################################################################
# CAS Mailbox
###############################################################################
Get-CASMailbox -Identity m.muster@icewolf.ch | fl imap*
Set-CASMailbox -Identity m.muster@icewolf.ch -PopEnabled $true -ImapEnabled $true



You also need to give "Full Access" Permission to the Service Principal of the App

###############################################################################
#Full Access
###############################################################################
$Mailbox = "m.muster@icewolf.ch"
$SericePrincipal = "EXO Serviceprincipal DemoEXO-POP3-IMAP"
Add-MailboxPermission -Identity $Mailbox -User $SericePrincipal -AccessRights FullAccess -AutoMapping $false



Check Full Access Permissions

$Mailbox = "m.muster@icewolf.ch"
Get-MailboxPermission  -Identity $Mailbox | Where-Object { ($_.AccessRights -eq "FullAccess") -and ($_.IsInherited -eq $false) -and -not ($_.User -like "NT AUTHORITY\SELF") } | ft -AutoSize



Now you can check with this tool


###############################################################################
# Test Access
###############################################################################
Clear-MsalTokenCache
$AppID = "3bf0cf36-87bf-47a9-927b-0ef9df7cf146"
$TenantID = "icewolfch.onmicrosoft.com"
$ClientSecret = "YourClientSecret"
$Scope = "https://outlook.office.com/IMAP.AccessAsUser.All"
.\Get-IMAPAccessToken.ps1 -tenantID $TenantID  -clientId $AppID -clientsecret $ClientSecret -targetMailbox "m.muster@icewolf.ch"


That's how it looks like if your IMAP Protocol in Get-CASMailbox is not enabled (And it takes a while 30-60 Minutes) after the Change to become active.


Here we go



You can also use Remote Connectivity Analyzer to verify the IMAP Access.

Microsoft Remote Connectivity Analyzer







Check out also other ways of Testing your IMAP OAuth2 Flow

Regards
Andres Bohren