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

Ya no es tan sencillo. Para establecer una conexión mediante OAuth2, ahora es necesario obtener primero el token de acceso. Esto implica superar 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 hecho esto, el resto es pan comido. Dado que barbushin/php-imap no admite oAuth2, puedes, por ejemplo, establecer una conexión utilizando la biblioteca alternativa Webklex/php-imap (que además tiene la ventaja de no requerir el módulo PHP IMAP ).:

734a82898010e2fcb02c72c3cd9702c2

Pero las bibliotecas que no soportan oficialmente oAuth2 también se pueden usar con la ayuda de 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: aquí tampoco hay forma de evitar oAuth2 ya que la autenticación básica está desactivada. Después de agregar el permiso "SMTP.SendAsApp" en el registro de la aplicación de Azure y otorgar el consentimiento del administrador, se puede realizar el envío, por ejemplo. 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