Dostęp z PHP do Exchange/Office 365

Długo ogłaszane - teraz rzeczywistość : Microsoft wyłączył uwierzytelnianie hasłem dla niektórych protokołów w Exchange Online od września 2022 na rzecz oAuth2. Problemy z GitHubem wielu bibliotek i skryptów do tworzenia kopii zapasowych jasno pokazują, że przejście zaskoczyło wielu administratorów. Poniżej pokazujemy, w jaki sposób możesz nadal uzyskiwać dostęp do zawartości skrzynki pocztowej Exchange za pomocą oAuth2 przez PHP przez IMAP.


Z punktu widzenia bezpieczeństwa posunięcie Microsoftu jest bardzo słuszne, ale złożoność programistycznego dostępu do jego e-maili znacznie wzrosła. Na przykład, jeśli korzystasz z powszechnie używanej biblioteki barbushin/php-imap , dostęp wyglądał następująco:

734a82898010e2fcb02c72c3cd9702c2

Po prostu już nie działa. Aby nawiązać połączenie przez oAuth2, pierwszą trudnością jest zdobycie tokena dostępu. A do tego trzeba pokonać dwie przeszkody.

Azure Active Directory

Poniższe kroki rejestrują nową aplikację w Azure Active Directory:

Zaloguj się do https://portal.azure.com
Otwórz „Azure Active Directory”
Wybierz „Rejestracje aplikacji” i „Nowa rejestracja”.
Skopiuj „Identyfikator aplikacji (klient)” (=identyfikator klienta) i „identyfikator katalogu (dzierżawca)” (=identyfikator najemcy).
„Uprawnienia API” i „Dodaj uprawnienia”
„Interfejsy API używane przez moją organizację” i „Office 365 Exchange Online”
„Uprawnienia aplikacji” i „IMAP.AccessAsApp”
Udziel zgody administratora
„Certyfikaty i tajemnice” i „Tajemnice klienta” i „Nowy sekret klienta”
Wybierz opis i ustaw ważność
Skopiuj „Secret ID” (Sekret klienta) do schowka
Otwarte aplikacje korporacyjne
Skopiuj „Identyfikator obiektu”.

PowerShell

Teraz włączamy aplikację w Microsoft PowerShell (tryb administratora) i przypisz uprawnienia do poszczególnych skrzynek pocztowych (<TENANTID>, <CLIENTID>, <OBJECTID>, <EMAIL> należy wymienić w każdym przypadku):

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

Kiedy już to zrobisz, reszta to już nie nauka o rakietach. Ponieważ barbushin/php-imap nie obsługuje oAuth2, możesz połączyć się z alternatywną biblioteką Webklex/php-imap (która również ma tę zaletę, że nie wymaga modułu PHP IMAP ).:

734a82898010e2fcb02c72c3cd9702c2

Jednak biblioteki, które oficjalnie nie obsługują oAuth2 mogą być również używane z serwerem proxy, takim jak simonrob/e-mail-oauth2-proxy sprawić, by było to wykonalne. Po tym Ściągnij a instalacja przez python -m pip install -r requirements-no-gui.txt (Wymagany Python ≥3.6) edytujesz plik emailproxy.config np. w następujący sposób (zastępując ten czas <TENANTID>, <CLIENTID>, <CLIENTSECRET> oraz <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>

Następnie uruchamiasz serwer proxy za pomocą python emailproxy.py --no-gui i może teraz przejść do niezaszyfrowanego adresu IP localhost na porcie 1993 połącz się za pomocą zwykłego uwierzytelniania podstawowego (i dowolnego ustawionego hasła). Jeśli chcesz uruchomić proxy jako usługę w tle podczas uruchamiania systemu, możesz użyć np 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

Jeśli wymagane jest szyfrowane połączenie, jest to również możliwe - w tym celu najpierw tworzysz klucz prywatny i samopodpisany certyfikat:

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

Następnie następuje odniesienie w emailproxy.config te dwa pliki:

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