Adgang med PHP til Exchange/Office 365

Længe annonceret - nu virkelighed : Microsoft har slået autentificering med adgangskode fra for visse protokoller i Exchange Online fra september 2022 til fordel for oAuth2. GitHub-problemerne i mange biblioteker og backup-scripts gør det klart, at skiftet overraskede mange administratorer. Nedenfor viser vi en måde, hvordan du kan fortsætte med at få adgang til indholdet af din Exchange-postkasse ved hjælp af oAuth2 via PHP via IMAP.


Fra et sikkerhedssynspunkt er Microsofts træk meget korrekt, men kompleksiteten af ​​programmatisk adgang til dets e-mails er steget en del. For eksempel, hvis du bruger det meget udbredte barbushin/php-imap bibliotek , plejede adgangen at være som følger:

734a82898010e2fcb02c72c3cd9702c2

Det virker bare ikke længere. For at etablere en forbindelse via oAuth2 er den første vanskelighed at få adgangstokenet. Og for dette skal du tage to forhindringer.

Azure Active Directory

Følgende trin registrerer en ny app i Azure Active Directory:

Log ind på https://portal.azure.com
Åbn "Azure Active Directory"
Vælg "App registreringer" & "Ny registrering".
Kopiér "Applikations-id (klient)" (=klient-id) & "katalog-id (lejer)" (=lejer-id).
"API-tilladelser" og "Tilføj tilladelse"
"API'er brugt af min organisation" og "Office 365 Exchange Online"
"Applikationstilladelser" og "IMAP.AccessAsApp"
Giv administratorsamtykke
"Certifikater og hemmeligheder" & "Kundehemmeligheder" & "Ny klienthemmelighed"
Vælg beskrivelse og indstil gyldighed
Kopier "Secret ID" (Client Secret) til udklipsholderen
Åbn virksomhedsapplikationer
Kopier "Objekt ID".

PowerShell

Nu slår vi appen ind Microsoft PowerShell (Administratortilstand) og tildel tilladelser til de individuelle postkasser (<TENANTID>, <CLIENTID>, <OBJECTID>, <EMAIL> skal udskiftes i hvert enkelt tilfælde):

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

Når du har gjort det, er resten ikke raketvidenskab. Da barbushin/php-imap ikke understøtter oAuth2, kan du oprette forbindelse til det alternative bibliotek Webklex/php-imap (som også har den fordel, at det ikke kræver PHP IMAP-modulet ).:

734a82898010e2fcb02c72c3cd9702c2

Biblioteker, der ikke officielt understøtter oAuth2, kan dog også bruges med en proxy som f.eks simonrob/email-oauth2-proxy gøre det brugbart. Efter dette Hent og installationen via python -m pip install -r requirements-no-gui.txt (Python ≥3.6 påkrævet) redigerer du filen emailproxy.config fx som følger (erstatter denne gang <TENANTID>, <CLIENTID>, <CLIENTSECRET> og <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>

Så starter du proxyen med python emailproxy.py --no-gui og kan nu gå til IP'en ukrypteret localhost på havn 1993 opret forbindelse via almindelig Basic Auth (og en hvilken som helst adgangskode). Hvis du vil starte proxyen som en tjeneste i baggrunden, når du starter systemet, kan du bruge f.eks 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

Hvis en krypteret forbindelse er påkrævet, er dette også muligt - til dette opretter du først en privat nøgle og et selvsigneret certifikat:

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

Derefter henvises der i emailproxy.config disse to filer:

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