Accès avec PHP à Exchange/Office 365

Longtemps annoncé - maintenant réalité : Microsoft a désactivé l'authentification par mot de passe pour certains protocoles dans Exchange Online à partir de septembre 2022 au profit de oAuth2. Les problèmes GitHub de nombreuses bibliothèques et scripts de sauvegarde montrent clairement que le changement a pris de nombreux administrateurs par surprise. Ci-dessous, nous montrons comment vous pouvez continuer à accéder au contenu de votre boîte aux lettres Exchange à l'aide de oAuth2 via PHP via IMAP.


D'un point de vue sécurité, la décision de Microsoft est très correcte, mais la complexité de l'accès programmatique à ses e-mails a considérablement augmenté. Par exemple, si vous utilisez la bibliothèque barbushin/php-imap largement utilisée, l'accès était le suivant:

734a82898010e2fcb02c72c3cd9702c2

Cela ne fonctionne plus. Afin d'établir une connexion via oAuth2, la première difficulté est d'obtenir le jeton d'accès. Et pour cela, vous devez surmonter deux obstacles.

Azure Active Directory

Les étapes suivantes enregistrent une nouvelle application dans Azure Active Directory:

Connectez-vous à https://portal.azure.com
Ouvrez le "Azure Active Directory"
Sélectionnez "Enregistrements d'applications" et "Nouvelle inscription".
Copiez "Application ID (Client)" (=Client ID) & "Directory ID (Tenant)" (=Tenant ID).
"Autorisations API" et "Ajouter une autorisation"
"API utilisées par mon organisation" & "Office 365 Exchange Online"
"Autorisations d'application" et "IMAP.AccessAsApp"
Accorder le consentement de l'administrateur
« Certificats et secrets » et « Secrets client » et « Nouveau secret client »
Choisissez la description et définissez la validité
Copiez "Secret ID" (Client Secret) dans le presse-papiers
Applications d'entreprise ouvertes
Copiez "ID d'objet".

PowerShell

Maintenant, nous tournons l'application dans le MicrosoftPowerShell (mode administrateur) et attribuez des autorisations aux boîtes aux lettres individuelles (<TENANTID>, <CLIENTID>, <OBJECTID>, <EMAIL> doit être remplacé dans chaque cas):

Install-Module -Name ExchangeOnlineManagement
Import-Module ExchangeOnlineManagement
Connect-ExchangeOnline -Organization <TENANTID>

New-ServicePrincipal -AppId <CLIENTID> -ServiceId <OBJECTID>
Add-MailboxPermission -Identity "<EMAIL>" -User <OBJECTID> -AccessRights FullAccess
...

Une fois que vous avez fait cela, le reste n'est pas sorcier. Comme barbushin/php-imap ne supporte pas oAuth2, vous pouvez vous connecter avec la bibliothèque alternative Webklex/php-imap (qui a aussi l'avantage de ne pas nécessiter le module PHP IMAP ).:

734a82898010e2fcb02c72c3cd9702c2

Cependant, les bibliothèques qui ne prennent pas officiellement en charge oAuth2 peuvent également être utilisées avec un proxy tel que simonrob/email-oauth2-proxy le rendre exploitable. Après ça Télécharger et l'installation via python -m pip install -r requirements-no-gui.txt (Python ≥3.6 requis) vous éditez le fichier emailproxy.config par exemple comme suit (remplaçant cette fois <TENANTID>, <CLIENTID>, <CLIENTSECRET> et <EMAIL>):

[Server setup]

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

[Account setup]

[<EMAIL>]
token_url = https://login.microsoftonline.com/<TENANTID>/oauth2/v2.0/token
oauth2_scope = https://outlook.office365.com/.default
redirect_uri = http://localhost:8080
client_id = <CLIENTID>
client_secret = <CLIENTSECRET>

Ensuite, vous démarrez le proxy avec python emailproxy.py --no-gui et peut maintenant accéder à l'adresse IP non cryptée localhost sur bâbord 1993 connectez-vous via Basic Auth (et tout mot de passe défini). Si vous souhaitez démarrer le proxy en tant que service en arrière-plan lorsque vous démarrez le système, vous pouvez utiliser, par exemple systemd:

sudo systemctl edit --force --full emailproxy.service

[Unit]
Description=Email OAuth 2.0 Proxy
[Service]
ExecStart=/usr/bin/python /path/to/emailproxy.py --no-gui
Restart=always
[Install]
WantedBy=multi-user.target

sudo systemctl enable emailproxy.service --now
sudo systemctl status emailproxy.service
sudo systemctl start emailproxy.service

Si une connexion cryptée est requise, cela est également possible - pour cela, vous créez d'abord une clé privée et un certificat auto-signé:

openssl genrsa -out key.pem 3072
openssl req -new -x509 -key key.pem -out cert.pem -days 360

Il est alors fait référence dans le emailproxy.config ces deux fichiers:

local_key_path = /path/to/key.pem
local_certificate_path = /path/to/cert.pem

Envoi d'e-mails

Toute personne souhaitant envoyer des e-mails par programmation via Microsoft Exchange Online est confrontée à un changement fondamental : Microsoft a désactivé l’authentification classique par nom d’utilisateur et mot de passe pour le protocole SMTP dans Exchange Online. Ce qui se faisait en quelques lignes de code depuis des années nécessite désormais le recours à OAuth2, incluant l’enregistrement de l’application dans Azure Active Directory, les certificats et la gestion des jetons. Cette même approche peut être utilisée pour l’envoi et la réception d’e-mails.

"Autorisations API" et "Ajouter une autorisation"
"API utilisées par mon organisation" & "Office 365 Exchange Online"
« Autorisations de l’application » et « SMTP.SendAsApp »
Accorder le consentement de l'administrateur

L'envoi SMTP via Microsoft Exchange 365 suit le même principe que l'accès IMAP : depuis la désactivation de l'authentification de base, OAuth2 est la seule alternative. Après avoir ajouté l'autorisation « SMTP.SendAsApp » lors de l'enregistrement de l'application Azure et obtenu l'approbation de l'administrateur, l'envoi peut être effectué, par exemple, avec… PHPMailer Ceci est désormais implémenté. Au lieu de simplement soumettre un nom d'utilisateur et un mot de passe comme auparavant, l'authentification auprès du serveur SMTP utilise maintenant un jeton d'accès. smtp.office365.com:

734a82898010e2fcb02c72c3cd9702c2

L'effort de configuration supplémentaire peut paraître intimidant au premier abord, mais il s'avère payant à long terme : l'authentification basée sur OAuth2 est nettement plus sécurisée, car aucun mot de passe en clair n'a besoin d'être stocké dans les fichiers de configuration ou les scripts. De plus, le jeton d'accès peut être limité dans le temps et ses autorisations contrôlées avec une grande précision. Il convient également de mentionner la bibliothèque MailHelper , qui offre une API pratique pour la réception et l'envoi d'e-mails.

Retour