Proxy OAuth2 et SSL/TLS pour POP3 et IMAP4

Vous êtes en train de migrer vers Exchange Online sur Office 365.
Parmi vos applications critiques pour le business, l’une d’entre elles nécessite de se connecter à une boite en POP/IMAP. Bien évidemment, elle ne prend pas en charge la connexion en POP3S ou IMAP4S obligatoire dans Office 365. Pire que ça : vous apprenez que Microsoft vous oblige à utiliser l’authentification moderne (OAuth 2.0) dans les protocoles POPS/IMAPS.

Vous vous dites que tout est foutu. Mais non ! Nous avons une solution pour vous 🙂

Pour cela, nous nous appuyons sur l’excellent travail de Simon ROBINSON que vous pouvez trouver ici :

Architecture de la solution

Ici, nous avons décidé de mettre le proxy sur un serveur dédié pour une meilleure compréhension des flux, mais il est tout à fait possible de l’héberger directement sur le serveur applicatif.

Liste des étapes pour se connecter à la boite aux lettres :

  1. Le serveur applicatif se connecte au Proxy en POP3 ou IMAP4 non sécurisé
  2. Le Proxy se connecte à Entra ID pour obtenir un token pour l’authentification avec OAuth2
  3. Le Proxy se connecte à Exchange Online en POP3 sécurisé ou IMAP4 sécurisé
  4. Le Proxy s’authentifie en Modern Auth (OAuth2) avec le token qu’il vient de récupérer auprès d’Entra ID
  5. Le Proxy informe le serveur applicatif qu’il est connecté à la boite aux lettres, comme si ce dernier s’était connecté via login/password
  6. Le serveur applicatif passe les commandes POP ou IMAP classiques pour récupérer le courrier dans la boite

Fichier de config emailproxy.config

[Email OAuth 2.0 Proxy configuration file]

[Server setup]

[POP-1995]
server_address = outlook.office365.com
server_port = 995
local_address = 127.0.0.1

[IMAP-1993]
server_address = outlook.office365.com
server_port = 993
local_address = 127.0.0.1

[app@yourdomain.com]
documentation = *** note: this is an advanced O365 account example; in most cases you want the version above instead ***
token_url = https://login.microsoftonline.com/Your-Tenant-Guid/oauth2/v2.0/token
oauth2_scope = https://outlook.office365.com/.default
oauth2_flow = client_credentials
redirect_uri = http://localhost
client_id = XXXXX
client_secret = YYYYY

[Advanced proxy configuration]

[emailproxy]
delete_account_token_on_password_error = True
encrypt_client_secret_on_first_use = False

Il vous restera à remplacer dans le fichier de configuration :

Application Entra ID

Permissions de l’application

Pour chaque compte (boite aux lettres) qui va être déclaré dans la passerelle, il faudra lui associer une application Entra ID dédiée via un Client ID et Client Secret. Pour des raisons de sécurité, il est préférable de créer une application Entra ID avec un Service Principal pour chacune des boites aux lettres concernées.

App Registration

Aller dans Entra ID puis dans Applications > App Registrations.App Registrations
Cliquer sur New registration pour créer une nouvelle appli.
Donner un nom explicite qui permettra de la retrouver facilement et sélectionner Accounts in this organizational directory only.
Dans Redirect URI, sélectionner Web puis saisir http://localhost (attention à bien saisir http et non https).
 
Enfin, cliquer sur Register.

Permissions de l’application

Se rendre dans API permissions puis cliquer sur Add a permission.
Sélectionner APIs my organization uses et sélectionner Office 365 Exchange Online.
Sélectionner IMAP.AccessAsApp ou POP.AccessAsApp en fonction du protocole que vous souhaitez utiliser pour accéder à la boite aux lettres.
 
Vous pouvez aussi ajouter SMTP.SendAsApp si vous souhaitez faire de l’envoi SMTP authentifié via la même application.
Enfin, cliquer sur Grant admin consent pour rendre les permissions effectives.
Optionnellement, vous pouvez supprimer la permission User.Read qui n’est pas nécessaire.

Création du secret

Dans Certificates & secrets, cliquer sur New client secret.
Créer un secret avec la validité que vous souhaitez puis cliquer sur Add.
Prendre note de l’attribut Value avant d’aller plus loin puisqu’il ne sera plus lisible une fois la page quittée.
L’attribut Secret ID ne nous intéresse pas.
Noter aussi l’Application ID qu’il faudra ajouter dans le fichier de configuration du proxy.

Donner les droits à l’application Entra sur la Mailbox

#Connect Azure and Exchange Online
Connect-AzAccount 
Connect-ExchangeOnline


#Create Service Principal in Exchange Online
$objAzApp = Get-AzADServicePrincipal -SearchString "POP3 - myapp@epsight.fr"
$strAzAppId = $AADServicePrincipalDetails.AppId
$strAzObjId = $AADServicePrincipalDetails.Id
$strSPDisplayName = "EXO Serviceprincipal for EntraAD App $($objAzApp.Displayname)"

New-ServicePrincipal -AppId $strAzAppId -ObjectId $strAzObjId -DisplayName $strSPDisplayName


#Add permissions on mailbox
$objEXOServicePrincipal = Get-ServicePrincipal -Identity $strSPDisplayName

Add-MailboxPermission -Identity "myapp@epsight.fr" -User $objEXOServicePrincipal.Identity -AccessRights FullAccess

Compiler le script Python en executable

Si vous souhaitez pouvoir utiliser le script Python comme un exécutable autonome, vous pouvez faire les actions ci-dessous après avoir installé Python 3.11 sur votre machine :

pip install -r requirements-core.txt
pip install -r requirements-gui.txt

pip install pyinstaller

pyinstaller --onefile emailproxy.py

Lancer le proxy une fois compilé

L’interface graphique n’est pas utile dans notre cas avec le fichier de configuration que nous avons créé. Vous pouvez donc lancer le proxy sans interface graphique avec la ligne de commande qui suit.

emailproxy.exe --no-gui