Accesso con PHP a Exchange/Office 365

Annunciato da tempo , ora realtà : Microsoft ha disattivato l'autenticazione tramite password per alcuni protocolli in Exchange Online da settembre 2022 a favore di oAuth2. I problemi di GitHub di molte librerie e script di backup chiariscono che il passaggio ha colto di sorpresa molti amministratori. Di seguito mostriamo un modo per continuare ad accedere ai contenuti della tua casella di posta Exchange con l'aiuto di oAuth2 tramite PHP tramite IMAP.


Dal punto di vista della sicurezza, la mossa di Microsoft è molto corretta, ma la complessità dell'accesso programmatico alle sue e-mail è aumentata parecchio. Ad esempio, se si utilizza la libreria barbushin/php-imap ampiamente utilizzata, l'accesso era il seguente:

734a82898010e2fcb02c72c3cd9702c2

Semplicemente non funziona più. Per stabilire una connessione tramite oAuth2, la prima difficoltà è ottenere il token di accesso. E per questo devi affrontare due ostacoli.

Azure Active Directory

I passaggi seguenti registrano una nuova app in Azure Active Directory:

Accedi a https://portal.azure.com
Apri "Azure Active Directory"
Seleziona "Iscrizioni app" e "Nuova registrazione".
Copia "ID applicazione (client)" (=ID client) e "ID directory (tenant)" (=ID tenant).
"Autorizzazioni API" e "Aggiungi autorizzazione"
"API utilizzate dalla mia organizzazione" e "Office 365 Exchange Online"
"Autorizzazioni dell'applicazione" e "IMAP.AccessAsApp"
Concedi il consenso dell'amministratore
"Certificati e segreti" e "Segreti del cliente" e "Segreto del nuovo cliente"
Scegli la descrizione e imposta la validità
Copia "Secret ID" (Client Secret) negli appunti
Apri applicazioni aziendali
Copia "ID oggetto".

PowerShell

Ora trasformiamo l'app in Microsoft PowerShell (Modalità amministratore) e assegnare i permessi alle singole caselle di posta (<TENANTID>, <CLIENTID>, <OBJECTID>, <EMAIL> deve essere sostituito in ogni 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 volta che l'hai fatto, il resto non è scienza missilistica. Poiché barbushin/php-imap non supporta oAuth2, puoi connetterti con la libreria alternativa Webklex/php-imap (che ha anche il vantaggio di non richiedere il modulo PHP IMAP ).:

734a82898010e2fcb02c72c3cd9702c2

Tuttavia, le librerie che non supportano ufficialmente oAuth2 possono essere utilizzate anche con un proxy come simonrob/email-oauth2-proxy renderlo praticabile. Dopodichè Scarica e l'installazione tramite python -m pip install -r requirements-no-gui.txt (Python ≥3.6 richiesto) si modifica il file emailproxy.config ad esempio come segue (sostituendo questa volta <TENANTID>, <CLIENTID>, <CLIENTSECRET> e <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>

Quindi avvii il proxy con python emailproxy.py --no-gui e ora può andare all'IP non crittografato localhost sul porto 1993 connettersi tramite la normale autenticazione di base (e qualsiasi password impostata). Se si desidera avviare il proxy come servizio in background all'avvio del sistema, è possibile utilizzare, ad esempio sistema:

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

Se è richiesta una connessione crittografata, anche questo è possibile: per questo devi prima creare una chiave privata e un certificato autofirmato:

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

Poi si fa riferimento al emailproxy.config questi due file:

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