3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

OSの死活監視やバックアップ取得の成否メールなど、人によるメール送受信ではなくシステムによるメール送受信をExchange Onlineで実施する方法を自分なりに考えて実装してみたのでそのまとめです。
具体的な実装方法はタイトルの通りです。

Microsoft 365(Exchange Online)は「一人一アカウント(ひとり いちあかうんと)」の原則に基づいて設計されており、
人間以外のシステムプロセスやスクリプトがメール送受信に利用することは原則として想定されていません。
したがって、このような実装を行う場合はライセンス体系や運用ルールを十分確認のうえ、各自の責任で実施してください。

1つアカウントとライセンスを準備する

上述の警告のnote alertの通りシステムで利用するアカウントにライセンスが必要かどうかわかりませんでした。
ですのでとりあえず1つ専用のアカウントとExO Plan1のライセンスを準備して検証しました。

証明書を準備する

今回の用途だとメールを送信したいサーバやクライアント端末が存在するはずです。
登録したアプリケーションへの認証に証明書認証を使うため、証明書を作成します。

証明書発行手順

今回はWindows 11から登録されたアプリケーション経由でExOからメールを送りたいため、Windows 11にデフォルトで搭載されているPower Shellを用いて自己署名証明書を発行します。
以下のコマンドを実行します。

Create_cert.ps1
$certName = "cert_ExO_SystemMail01"
$CertStoreLocation =  "cert:\CurrentUser\My"
$KeyAlgorithm = "RSA"
$KeyLength = 2048
$KeySpec = "Signature"
$KeyExportPolicy =  "NonExportable"
$Expire_Years = "1"

$Cert01 = New-SelfSignedCertificate -Subject $certName -CertStoreLocation $CertStoreLocation -KeyAlgorithm $KeyAlgorithm -KeyLength $KeyLength -KeySpec $KeySpec -KeyExportPolicy $KeyExportPolicy -NotAfter (Get-Date).AddYears($Expire_Years)

$Thumbprint = $Cert01.thumbprint
Write-Output $Thumbprint

パラメーターは以下の通りです。

パラメーター名 変数名 本記事での設定値 説明
証明書名 $certName cert_ExO_SystemMail01 生成される証明書の識別名
証明書ストア $CertStoreLocation cert:\CurrentUser\My 証明書の保存先(現在のユーザーの「個人」ストア)
鍵アルゴリズム $KeyAlgorithm RSA 公開鍵暗号方式を利用
鍵長 $KeyLength 2048 鍵の長さ(ビット数)
鍵の利用用途 $KeySpec Signature デジタル署名・認証用途(署名鍵専用で暗号化用途ではない)
鍵のエクスポートの可否 $KeyExportPolicy NonExportable 秘密鍵のエクスポートを禁止
証明書有効期限 $Expire_Years 1 証明書の有効期間(年単位)

ExOはExchange Onlineの略称です。
今回は実験的ですがRSAではなく楕円曲線暗号(ECDSA)を利用しました。

楕円曲線暗号(ECDSA)を使用すると「認証キーアルゴリズムはサポートされていません」というエラーが発生します。
これは、Microsoft Entra ID のアプリケーション証明書認証がRSAのみをサポートしているためです(記事執筆時の2025年11月3日現在)。
ECDSAはRSAと同等のセキュリティをより短い鍵長で実現できる優れた方式ですが、現行のMicrosoft GraphやMSALライブラリでは利用できません。
参考:Microsoft Learn - How to create a self-signed certificate for Microsoft Entra ID
image.png

また-KeyExportPolicy NonExportable により鍵(秘密鍵)のエクスポートもさせないようにしているので、証明書の複製や他OSへの移植も不可能です。
仮にこのメール送信を行うマシンが乗っ取られても、証明書を複製されてExOの踏み台サーバを増やされるリスクを低減しています。
証明書の有効期限はPower Shell内でAddYearsオプションを利用しているため年単位ですが、AddMonthsオプションだと月単位、AddWeeksだと週単位、AddDaysだと日単位での日数調整が可能です。
最近はセキュリティ強化の流れから、主要な認証局(CA)による証明書有効期間の短縮(最大398日)も進んでおり、短期証明書運用を想定した設計を行うことが望まれます。

証明書エクスポート手順

Power Shellで指定した証明書の作成先である[カレントユーザー(現在のユーザー)]を開くために[ファイル名を指定して実行]にcertmgr.mscと入力して[OK]をクリックします。
image.png

以下の画面が出てくるので、更に一つ下の階層の[個人]を開き更に[証明書]を開くと、先ほどPower Shellで作成した証明書が出てきます。
image.png

対象の証明書を右クリックして[すべてのタスク]をクリックし[エクスポート]をクリックします。
image.png

[証明書のエクスポート ウィザードの開始]画面が出てくるので[次へ]をクリックします。
image.png

秘密キー(秘密鍵)のエクスポートを選択する画面が出てくるので[いいえ、秘密キーをエクスポートしません]を選択して[次へ]をクリックします。
証明書作成時にオプションで-KeyExportPolicyのパラメーターをNonExportableを選択しているので秘密キーをエクスポートするラジオボタンがグレーアウトしていますね。
image.png

次にエクスポート形式を選択する画面になりますので、[DER]を選択して[次へ]をクリックします。
image.png

エクスポートする場所とファイル名を指定する画面が出てくるので、お好きな場所とファイル名を指定しましょう。
私はデスクトップに、ファイル名は証明書名と同じにしました。
image.png

最後に確認画面が出てくるので[完了]をクリックします。
image.png

証明書作成手順はここまでです。

Entra IDに専用のアプリケーションを登録する

Entra ID管理センターの[アプリの登録]からアプリケーションを登録します。

アプリケーション登録

Entra ID管理センターにログインし、[Entra ID]内の[アプリの登録]から[+新規登録]をクリックします。
image.png

[名前]に任意の名前を付けます。
私はわかりやすく[ExO_SystemMail01]にしました。
[サポートされているアカウントの種類]は、以前までは[この組織ディレクトリのみに含まれるアカウント]で良かったのですが、少し前から[任意の組織ディレクトリ内のアカウント(任意の Microsoft Entra ID テナント - マルチテナント)]でないと権限不足でエラーになります。
[リダイレクト URI]は今回のアプリ利用用途では不要なので設定しなくて大丈夫です。
最後に[登録]をクリックします。
image.png
登録されると以下の画面に遷移します。
image.png

登録したアプリケーションに証明書をインポートする

登録したアプリケーション内の[証明書とシークレット]をクリックし、[証明書]をクリックします。
[証明書のアップロード]というボタンが出てきますのでクリックします。
image.png

先ほどPower Shellで作成してエクスポートした証明書をアップロードして[追加]をクリックします。
image.png

正しく証明書がアップロードされたことを確認します。
image.png

登録されたアプリケーションに権限を付与する

登録したアプリケーションの中の[APIのアクセス許可]をクリックして、[アクセス許可の追加]をクリックします。(すみません。画像では途中で見切れていますが・・・)
右からブレードが出てきますので、一番大きい[Microsoft Graph]をクリックします。
image.png

Microsoft Graphの中でどの種類の許可を与えるか聞かれるので[アプリケーションの許可]を選択して、[アクセス許可の追加]をクリックします。
image.png

検索ボックスに[Mail.Sned]と入力し、検索結果で抽出される[Mail.Send]にチェックを入れて[アクセス許可の追加]をクリックします。
image.png

アクセス権の許可を与える際に管理者の同意を与える操作を実施します。
先ほどの[アクセス許可の追加]の隣にある[「テナント名」に管理者の同意を与えます]をクリックします。
[状態]のエクスクラメーションマークが状態遷移を表すので見ておきます。
image.png

[「テナント名」に管理者の同意を与えます]をクリックすると[管理者の同意の確認を与えます]画面が出てくるので[はい]をクリックします。
この操作により、登録したアプリケーションがテナント全体のMicrosoft Graph APIを利用できるようになります。Mail.Send権限は組織内すべてのユーザーのメール送信を許可する強い権限であるため、用途を限定して利用してください。
image.png

同意が与えられると[状態]のエクスクラメーションマークが緑のチェックマークに変化します。
image.png

これでアプリケーションの登録は終わりです。

メール送信テスト

では実際にメールが送信できるか検証してみます。
証明書と同じくPower Shellでメールを送付します。

初回実行のPower Shell

Init_Send_Mail.ps1
# モジュールインストール
Install-Module Microsoft.Graph.Users.Actions
Install-Module MSAL.PS

# モジュールインポート
Import-Module Microsoft.Graph.Users.Actions
Import-Module MSAL.PS

このモジュールのインストールとインポートは初回1回のみです。
MSAL認証とメール送信に必要なPower Shellモジュールのインストールとインポート(読み込み)です。

実際のメール送信用Power Shell

send_mail.ps1
# アプリ指定
$tenantId = '[テナントID]'
$clientId = '[登録したアプリケーションのクライアントID]'
$clientCert = Get-ChildItem -Path "Cert:\CurrentUser\My\[証明書の拇印]"
$MSALToken = Get-MsalToken -TenantId $tenantId -ClientId $clientId -ClientCertificate $clientCert

# Microsoft Graphログイン
$SecureAccessToken = ConvertTo-SecureString $MSALToken.AccessToken -AsPlainText -Force
Connect-MgGraph -AccessToken $SecureAccessToken -NoWelcome

# メール送信(Send-MgUserMail)
$Sender = "[送信元メールアドレス]"
$To     = "[送信先メールアドレス]"

$params = @{
  Message = @{
    Subject = "Graph app-only send test"
    Body    = @{ ContentType = "Text"; Content = "This is a test from app-only Graph (Power Shell)." }
    ToRecipients = @(@{ EmailAddress = @{ Address = $To } })
  }
  SaveToSentItems = $true
}

Send-MgUserMail -UserId $Sender -BodyParameter $params

以上でメール送信ができます。

証明書の拇印は証明書作成コマンドで最後にWrite-Outputコマンドで出力している変数$Thumbprintの値です。

-UserId パラメーターに指定する送信元アドレス ($Sender) は、アプリ登録に紐づくアカウントである必要があります。
異なるユーザーアドレスを指定すると「Access is denied」エラーになります。

まとめ

  1. OutlookやOWA以外からもメール送信が可能
  2. MSAL認証は証明書認証が使える
  3. 必要な権限はMail.Sendだけ

MSAL認証でこれまではシークレットを用いた事実上のID/パスワード認証しか知らなかったのですが、証明書認証での認証でメール送信者の身元確認ができるというのは驚きでした。
非常に便利ですね。

補足・応用の可能性

今回はExchange Onlineへのメール送信を例にしましたが、同じMSAL認証・証明書登録の仕組みを使えば、Microsoft Graphを経由してTeams通知やSharePoint更新などの自動化も可能です。

証明書認証により、パスワードレスかつセキュアにM365環境と連携できる点が最大のメリットです。

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?