Exchange/Office 365 への PHP によるアクセス

長い間発表されていましたが、現在の現実: Microsoft は、oAuth2 を優先して、2022 年 9 月から Exchange Online で特定のプロトコルのパスワードによる認証をオフにしました。 多くのライブラリバックアップ スクリプトの GitHub の問題は、切り替えが多くの管理者を驚かせたことを明らかにしています。 以下に、IMAP 経由で PHP 経由で oAuth2 を使用して、引き続き Exchange メールボックスのコンテンツにアクセスする方法を示します。


セキュリティの観点からは、Microsoft の動きは非常に正しいのですが、電子メールへのプログラムによるアクセスの複雑さがかなり増しています。 たとえば、広く使われているbarbusin/php-imap ライブラリを使用する場合、以前は次のようにアクセスしていました。:

734a82898010e2fcb02c72c3cd9702c2

もううまくいきません。 oAuth2 経由で接続を確立するには、まずアクセス トークンを取得する必要があります。 そのためには、2 つのハードルを乗り越える必要があります。

Azure アクティブ ディレクトリ

次の手順では、Azure Active Directory に新しいアプリを登録します:

https://portal.azure.comにログイン
「Azure Active Directory」を開きます
「アプリの登録」と「新規登録」を選択します。
「アプリケーションID(クライアント)」(=クライアントID)と「ディレクトリID(テナント)」(=テナントID)をコピーします。
「API 権限」と「権限の追加」
「組織で使用されている API」と「Office 365 Exchange Online」
「アプリケーションのアクセス許可」と「IMAP.AccessAsApp」
管理者の同意を与える
"Certificates & Secrets" & "Client Secrets" & "New Client Secret"
説明を選択して有効性を設定
「シークレットID」(クライアントシークレット)をクリップボードにコピー
エンタープライズ アプリケーションを開く
「オブジェクトID」をコピーします。

パワーシェル

次に、アプリを Microsoft PowerShell (管理者モード)、個々のメールボックスにアクセス許可を割り当てます (<TENANTID>, <CLIENTID>, <OBJECTID>, <EMAIL> その都度交換が必要です):

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

それができたら、残りはロケット科学ではありません。 barbusin /php-imapは oAuth2 をサポートしていないため、代替ライブラリWebklex/php-imapに接続できます (これには、 PHP IMAP モジュールを必要としないという利点もあります)。:

734a82898010e2fcb02c72c3cd9702c2

ただし、oAuth2 を公式にサポートしていないライブラリも、次のようなプロキシで使用できます。 simonrob/email-oauth2-proxy 実行可能にします。 この後 ダウンロード および経由のインストール python -m pip install -r requirements-no-gui.txt (Python ≥3.6 が必要) ファイルを編集する emailproxy.config 例)以下のように(今回は <TENANTID>, <CLIENTID>, <CLIENTSECRET><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>

次に、プロキシを開始します python emailproxy.py --no-gui 暗号化されていない IP にアクセスできるようになりました localhost ポート上 1993 通常の基本認証 (および任意のパスワード セット) を介して接続します。 システムの起動時にバックグラウンドでサービスとしてプロキシを起動する場合は、次のように使用できます。 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

暗号化された接続が必要な場合は、これも可能です。そのためには、最初に秘密鍵と自己署名証明書を作成します:

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

次に、参照が作成されます emailproxy.config この2つのファイル:

local_key_path = /path/to/key.pem
local_certificate_path = /path/to/cert.pem
バック