Acceso con PHP a Exchange/Office 365

Anunciado durante mucho tiempo , ahora realidad : Microsoft ha desactivado la autenticación por contraseña para ciertos protocolos en Exchange Online desde septiembre de 2022 a favor de oAuth2. Los problemas de GitHub de muchas bibliotecas y scripts de respaldo dejan en claro que el cambio tomó por sorpresa a muchos administradores. A continuación, mostramos una forma de cómo puede continuar accediendo al contenido de su buzón de Exchange con la ayuda de oAuth2 a través de PHP a través de IMAP.


Desde el punto de vista de la seguridad, la jugada de Microsoft es muy correcta, pero la complejidad del acceso programático a sus correos electrónicos ha aumentado bastante. Por ejemplo, si utiliza la biblioteca barbushin/php-imap ampliamente utilizada, el acceso solía ser el siguiente:

734a82898010e2fcb02c72c3cd9702c2

Simplemente ya no funciona. Para establecer una conexión a través de oAuth2, la primera dificultad es conseguir el token de acceso. Y para ello hay que enfrentarse a dos obstáculos.

Directorio activo de Azure

Los siguientes pasos registran una nueva aplicación en Azure Active Directory:

Iniciar sesión en https://portal.azure.com
Abra el "Directorio activo de Azure"
Seleccione "Registros de aplicaciones" y "Nuevo registro".
Copie "ID de aplicación (cliente)" (= ID de cliente) y "ID de directorio (inquilino)" (= ID de inquilino).
"Permisos de API" y "Agregar permiso"
"API utilizadas por mi organización" y "Office 365 Exchange Online"
"Permisos de la aplicación" y "IMAP.AccessAsApp"
Otorgar consentimiento de administrador
"Certificados y secretos" y "Secretos del cliente" y "Secreto del nuevo cliente"
Elija la descripción y establezca la validez
Copie "Secret ID" (Client Secret) al portapapeles
Aplicaciones empresariales abiertas
Copie "ID de objeto".

Potencia Shell

Ahora activamos la aplicación en el Microsoft PowerShell (modo Administrador) y asigne permisos a los buzones individuales (<TENANTID>, <CLIENTID>, <OBJECTID>, <EMAIL> debe ser reemplazado en cada caso):

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
...

Una vez que haya hecho eso, el resto no es ciencia espacial. Dado que barbushin/php-imap no es compatible con oAuth2, puede conectarse con la biblioteca alternativa Webklex/php-imap (que también tiene la ventaja de no requerir el módulo PHP IMAP ).:

734a82898010e2fcb02c72c3cd9702c2

Sin embargo, las bibliotecas que no admiten oficialmente oAuth2 también se pueden usar con un proxy como simonrob/email-oauth2-proxy hacerlo viable. Después de este Descargar y la instalación a través de python -m pip install -r requirements-no-gui.txt (Python ≥3.6 requerido) editas el archivo emailproxy.config por ejemplo, de la siguiente manera (reemplazando esta vez <TENANTID>, <CLIENTID>, <CLIENTSECRET> y <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>

Luego inicias el proxy con python emailproxy.py --no-gui y ahora puede ir a la IP sin cifrar localhost en el puerto 1993 conéctese a través de la autenticación básica normal (y cualquier contraseña establecida). Si desea iniciar el proxy como un servicio en segundo plano cuando inicia el sistema, puede usar, por ejemplo sistemad:

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 se requiere una conexión encriptada, esto también es posible; para esto, primero debe crear una clave privada y un certificado autofirmado.:

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

Luego se hace referencia en el emailproxy.config estos dos archivos:

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

Envío de correo electrónico

Cualquiera que desee enviar correos electrónicos mediante programación a través de Microsoft Exchange Online se enfrenta a un cambio fundamental: Microsoft ha deshabilitado la autenticación clásica con nombre de usuario y contraseña para SMTP en Exchange Online. Lo que se lograba con solo unas pocas líneas de código durante años ahora requiere un desvío a través de OAuth2, que incluye el registro de aplicaciones en Azure Active Directory, certificados y la gestión de tokens. Además de recibir correos electrónicos, también podemos implementar el envío según corresponda.

"Permisos de API" y "Agregar permiso"
"API utilizadas por mi organización" y "Office 365 Exchange Online"
"Permisos de la aplicación" y "SMTP.SendAsApp"
Otorgar consentimiento de administrador

El envío SMTP a través de Microsoft Exchange 365 sigue el mismo principio que el acceso IMAP: desde la desactivación de la autenticación básica, no hay alternativa a OAuth2. Tras agregar el permiso "SMTP.SendAsApp" en el registro de la aplicación de Azure y otorgar la aprobación del administrador, se puede realizar el envío, por ejemplo, con... PHPMailer Esto ya está implementado. En lugar de simplemente enviar un nombre de usuario y una contraseña como antes, la autenticación con el servidor SMTP ahora utiliza un token de acceso. smtp.office365.com:

734a82898010e2fcb02c72c3cd9702c2

El esfuerzo adicional de configuración puede parecer abrumador al principio, pero a la larga compensa: la autenticación basada en OAuth2 es significativamente más segura, ya que no es necesario almacenar contraseñas de texto plano en archivos de configuración ni scripts, y el token de acceso también puede tener un límite de tiempo y sus permisos pueden controlarse con gran precisión. Cabe mencionar también la biblioteca mailhelper , que ofrece una práctica API para recibir y enviar correos electrónicos.

Atrás