PHP ile Exchange/Office 365'e Erişim

Uzun zamandır duyurulan - şimdi gerçek : Microsoft, Eylül 2022'den itibaren Exchange Online'daki belirli protokoller için parola ile kimlik doğrulamasını oAuth2 lehine kapattı. Birçok kitaplığın ve yedekleme komut dosyasının GitHub sorunları, geçişin birçok yöneticiyi şaşırttığını açıkça ortaya koyuyor. Aşağıda, IMAP aracılığıyla PHP aracılığıyla oAuth2 yardımıyla Exchange posta kutunuzun içeriğine nasıl erişmeye devam edebileceğinizi gösteriyoruz.


Güvenlik açısından, Microsoft'un hareketi çok doğru, ancak e-postalarına programlı erişimin karmaşıklığı biraz arttı. Örneğin, yaygın olarak kullanılan barbushin/php-imap kitaplığını kullanıyorsanız, erişim eskiden şu şekildeydi:

734a82898010e2fcb02c72c3cd9702c2

Artık çalışmıyor. oAuth2 üzerinden bağlantı kurmak için ilk zorluk erişim belirtecini elde etmektir. Ve bunun için iki engeli aşmanız gerekiyor.

Azure Etkin Dizini

Aşağıdaki adımlar, Azure Active Directory'de yeni bir uygulamayı kaydeder:

https://portal.azure.com' ye giriş yapın
"Azure Active Directory"yi açın
"Uygulama kayıtları" ve "Yeni kayıt"ı seçin.
"Uygulama Kimliği (Müşteri)" (=Müşteri Kimliği) & "Dizin Kimliği (Kiracı)" (=Kiracı Kimliği) kopyalayın.
"API İzinleri" & "İzin Ekle"
"Kuruluşum tarafından kullanılan API'ler" & "Office 365 Exchange Online"
"Uygulama İzinleri" & "IMAP.AccessAsApp"
Yönetici izni ver
"Sertifikalar ve Sırlar" & "Müşteri Sırları" & "Yeni Müşteri Sırrı"
Açıklamayı seçin ve geçerliliği ayarlayın
"Gizli Kimliği" (Müşteri Sırrı) panoya kopyalayın
Açık kurumsal uygulamalar
"Nesne Kimliği"ni kopyalayın.

Güç kalkanı

Şimdi uygulamayı çeviriyoruz Microsoft PowerShell (Yönetici modu) ve ayrı posta kutularına izinler atayın (<TENANTID>, <CLIENTID>, <OBJECTID>, <EMAIL> her durumda değiştirilmelidir):

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

Bunu yaptıktan sonra, gerisi roket bilimi değildir. barbushin/php-imap oAuth2'yi desteklemediğinden, Webklex/php-imap alternatif kitaplığına bağlanabilirsiniz (bu, PHP IMAP modülünü gerektirmeme avantajına da sahiptir).:

734a82898010e2fcb02c72c3cd9702c2

Ancak, resmi olarak oAuth2'yi desteklemeyen kitaplıklar, aşağıdakiler gibi bir proxy ile de kullanılabilir: simonrob/email-oauth2-proxy uygulanabilir hale getirin. Bundan sonra İndirmek ve üzerinden kurulum python -m pip install -r requirements-no-gui.txt (Python ≥3.6 gerekli) dosyayı düzenlersiniz emailproxy.config örneğin aşağıdaki gibi (bu zamanı değiştirerek <TENANTID>, <CLIENTID>, <CLIENTSECRET> ve <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>

Sonra proxy'yi başlatırsınız python emailproxy.py --no-gui ve artık şifrelenmemiş IP'ye gidebilir localhost limanda 1993 normal Temel Kimlik Doğrulama (ve herhangi bir parola seti) aracılığıyla bağlanın. Sistemi başlattığınızda proxy'yi arka planda bir hizmet olarak başlatmak istiyorsanız, örneğin kullanabilirsiniz. sistemd:

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

Şifreli bir bağlantı gerekiyorsa, bu da mümkündür - bunun için önce bir özel anahtar ve kendinden imzalı bir sertifika oluşturursunuz:

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

Daha sonra referans yapılır emailproxy.config bu iki dosya:

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