3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【.NET C#】Microsoft365アカウントで先進認証使用のメール送信

Posted at

はじめに

Microsoft365のメールサーバを利用して、Windows上の.NET コンソールプログラムからメール送信をするのに、基本認証が使用出来なくなってしまったようで(※2022/12/8現在)、OAuthなる認証を使用して、Tokenを取得してからのメール送信までやってみました。

送信元となるアカウントはMicrosoft365の管理者権限を保有しないユーザを想定していますが、一部に管理者権限を必要とする操作があります。

Azure Potalでの設定(管理者権限なし)

STMP送信のAPIを利用可能なアプリの登録をします。

  1. メール送信元となるMicrosoft365アカウントでAzure Potalにログインします。
    image.png

  2. 左上”ポータルメニュー”からAzure Active Directoryをクリックします。
    image.png

  3. アプリの登録をクリックします。
    image.png

  4. 新規登録をクリックします。
    image.png

  5. 名前には任意の名称を入力します。(ここではsend_mailとしました)
    サポートされているアカウントの種類はデフォルトのこの組織ディレクトリのみに含まれるアカウントを選択します。
    登録ボタンを押します。
    image.png

  6. 新規アプリが作成され、各種IDが生成されています。(マスクで隠している箇所です)
    アプリケーション (クライアント) IDディレクトリ (テナント) IDはToken取得の際に必要な項目となります。
    APIのアクセス許可をクリックします。
    image.png

  7. アクセス許可の追加をクリックします。
    image.png

  8. Microsoft Graphをクリックします。
    image.png

  9. 委任されたアクセス許可をクリックします。
    image.png

  10. 検索窓に”smtp”と入力すると、下にアクセス許可の候補として表示されます。
    SMTP.Sendをチェックをして、アクセス許可の追加ボタンを押します。
    image.png

  11. アクセス許可SMTP_Sendが追加されています。
    認証をクリックします。
    image.png

  12. プラットフォームを追加をクリックします。
    image.png

  13. モバイル アプリケーションとデスクトップ アプリケーションをクリックします。
    image.png

  14. リダイレクト URIhttps://login.microsoftonline.com/common/oauth2/nativeclient
    をチェックし、構成ボタンを押します。
    これはToken取得の際に必要な項目となります。
    image.png

  15. プラットフォームが追加されています。
    image.png

  16. サポートされているアカウントの種類はデフォルトのこの組織ディレクトリのみに含まれるアカウントをチェックします。
    パブリック クライアント フローを許可する次のモバイルとデスクトップのフローを有効にするはいにして、保存ボタンを押します。
    image.png

Azure Potalでの設定(※管理者権限あり)

送信元アカウントで作成したアプリに、許可を付与します。

  1. 管理者権限を保有するMicrosoft365アカウントでAzure Potalにログインします。
    image.png

  2. 左上”ポータルメニュー”からAzure Active Directoryをクリックします。
    image.png

  3. アプリの登録をクリックします。
    image.png

  4. すべてのアプリケーションタブをクリックすると、作成済みアプリsend_mailがあるのでクリックします。
    image.png

  5. APIのアクセス許可をクリックします。
    image.png

  6. [ポータル名]に管理者の同意を与えますをクリックします。
    image.png

  7. 管理者の同意の確認を与えます。はいボタンを押します。
    image.png

  8. 状態にチェックが表示されます。[ポータル名]に付与されましたとなりアクセス許可が委任されました。
    image.png

Microsoft365管理センターでの設定(※管理者権限あり)

送信元アカウントの認証済みSMTPを有効化します。

  1. 管理者権限を保有するアカウントでログインし、管理をクリックします。
    image.png

  2. 送信元アカウントをクリックします。(ここではguest1@xxx.onmicrosoft.com
    image.png

  3. メールタブをクリックします。
    image.png

  4. メール アプリを管理するをクリックします。
    image.png

  5. 認証済み SMTPをチェックし、変更の保存ボタンを押します。
    image.png

  6. 設定が変更されました。
    image.png

メール送信(.NET C#)

Windows10Pro21H2 .NET6.0.11にて検証しました。
追加ライブラリはMicrosoft.Identity.Client 4.48.1、MailKit 3.4.3 です。

Codespaces上でも動作したので、Linux・MacOSでもいけるはず。

// Azure Portalで登録したアプリのアプリケーション (クライアント)ID
private static string CLIENT_ID = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
// Azure Portalで登録したアプリのディレクトリ (テナント) ID
private static string TENAMT_ID = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"; 
// M365メールのアカウント(送信元アカウント)
private static string USER_ACCOUNT = "xxx@zzz.onmicrosoft.com"; 
// M365メールのパスワード
private static string USER_PASSWORD = "*****"; 
// 送信先メールアドレス
private static string TO_MAIL_ADDRESS = "aaai@bbb.com"; 

static void Main(string[] args)
{
    try
    {
        // トークン取得
        var accessToken = GetAccessToken();
        accessToken.Wait();

        // メール送信
        SendMail(accessToken.Result).Wait();
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.ToString());
        throw;
    }
}

/// <summary>
/// トークン取得
/// </summary>
/// <returns>認証結果</returns>
public static async Task<AuthenticationResult> GetAccessToken()
{
    var options = new PublicClientApplicationOptions
    {
        ClientId = CLIENT_ID,
        TenantId = TENAMT_ID,               
        RedirectUri = "https://login.microsoftonline.com/common/oauth2/nativeclient" // Azure PortalのリダイレクトURI
    };

    var publicClientApplication = PublicClientApplicationBuilder
        .CreateWithApplicationOptions(options)
        .Build();

    var scopes = new string[] {
                    "https://outlook.office.com/SMTP.Send",
    };
    var user = USER_ACCOUNT;
    var password = USER_PASSWORD;

    AuthenticationResult authToken = await publicClientApplication.AcquireTokenByUsernamePassword(scopes, user, password).ExecuteAsync();

    return authToken;
}

/// <summary>
/// メール送信
/// </summary>
/// <param name="authToken">認証結果</param>
static async Task SendMail(AuthenticationResult authToken)
{
    var oauth2 = new SaslMechanismOAuth2(authToken.Account.Username, authToken.AccessToken);

    var message = new MimeKit.MimeMessage();
    // 送信元アドレス
    message.From.Add(new MimeKit.MailboxAddress("ユーザー", USER_ACCOUNT));
    // 送信先アドレス
    message.To.Add(new MimeKit.MailboxAddress("テスト", TO_MAIL_ADDRESS));
    // CC、BCCを設定
    // message.Cc.Add("a@b.com");
    // message.Bcc.Add("aa@bb.com");
    // メールタイトル
    message.Subject = "subject";

    // 本文作成
    var textPart = new MimeKit.TextPart(MimeKit.Text.TextFormat.Plain);
    textPart.Text = "body";

    // MimeMessage作成
    message.Body = textPart;

    using (var client = new MailKit.Net.Smtp.SmtpClient())
    {
        await client.ConnectAsync("smtp.office365.com", 587, SecureSocketOptions.Auto);
        await client.AuthenticateAsync(oauth2);
        await client.SendAsync(message);
        await client.DisconnectAsync(true);
    }

    return;
}

参考サイト

3
4
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
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?