mursのColdFusionメモ

頭の中から抜け落ちていく情報をメモがわりに書き溜めていくブログです。

cfauthでOAuth 2.0認証+Office 365メールをSMTPで送信してみる

前回の続き、今回はメールを送信してみる。 自分がOffice365メールを触っていないことや、SMTPの理解不足から来るエラーに色々とつまずいてしまったので、とりあえずは出来た例を紹介する(今回もMicrosoft 365 開発者プログラムのサンプルユーザーを使用して、サンプルユーザー間でのメールの送信を試してみた)。

OAuth 2.0の認証の方法は前回と同じだ。scopeをscope="https://outlook.office.com/SMTP.Send"に変えたくらい。取得したアクセストークン(#res.access_token#)を使って、JavaMailでメールを送信する。前回見つけた先人の知恵にSMTPのプログラム例が書かれていたが、SMTPトランスポートに接続する確認で終わっている。TOやSUBJECT、メール本文の指定方法などが参考できるページを探していたら、かなり昔の記事(2007年だからCFMX7~8の時代)だが下記のページを見つけた。

blog.pengoworks.com

この記事を参考に、OAuth 2.0認証で取得したアクセストークンに変えれば良いはずだ。 JavaMailのマニュアルでプロパティも確認して、簡単のテキストメール送信プログラムを書いてみた。

jakarta.ee

<cfscript>
  user = "AdeleV@5h6nl3.onmicrosoft.com";
  access_token="#cfoauthで取得したアクセストークン
  subject = "メールの件名";
  addyTo = "送信先メールアドレス";
  addyFrom = "送信元メールアドレス";

  props = createObject("java", "java.util.Properties").init();
  props.put("mail.smtp.auth", "true");
  props.put("mail.smtp.auth.mechanisms", "XOAUTH2");
  props.put("mail.smtp.host","outlook.office365.com");
  props.put("mail.smtp.port", "587");
  props.put("mail.smtp.starttls.enable", "true");
  props.put("mail.smtp.starttls.required", "true");

  mailSession = createObject("java", "javax.mail.Session").getInstance(props, javacast("null", ""));
  recipientType = createObject("java", "javax.mail.Message$RecipientType");
  mimeMessage = createObject("java", "javax.mail.internet.MimeMessage").init(mailSession);

  addressFrom = createObject("java", "javax.mail.internet.InternetAddress").init(addyFrom);
  addressTo = createObject("Java", "javax.mail.internet.InternetAddress").init(addyTo);
  mimeMessage.setFrom(addressFrom);
  mimeMessage.addRecipient(recipientType.TO, addressTo); 
  mimeMessage.setSubject(subject);
  mimeMessage.setText("テストメール送信です","utf-8");
  
  transport = mailSession.getTransport("smtp");
  transport.connect(user, access_token);
  transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients());
  transport.close();
</cfscript>

前提

starttlsでメールを送信しているので、JVM引数(CF Administratorにログインして「サーバーの設定 > JavaJVM」ページを開いた『JVM引数』、または[cf_root]/{インスタンス(cfusion等)}/bin/jvm.configファイルの『java.args=』)に -Dmail.smtp.starttls.enable=true を追加する。

はまったこと

  • JVM引数を追加していなかったので、starttlsが有効になっていなかった

  • Unsupported or unrecognized SSL message や Connection refused: connect … 誤って、props.put("mail.smtp.ssl.enable", "true"); や mailSession.getTransport("smtps"); を指定してしまい、starttlsのつもりがsmtpsでメールを送信しようとしていたこと

  • 535 5.7.139 Authentication unsuccessful, SmtpClientAuthentication is disabled for the Tenant. … Office 365メールの「認証済み SMTP」の設定が無効(デフォルト:無効)だった。

    • Microsoft 365 管理センターを開き、「ユーザー > アクティブ ユーザー」
    • メール送信元ユーザーを選択。ポップアップが表示されるので[メール]→ 「メール アプリ」で、[メール アプリの管理] を選択
    • [認証済み SMTP] の設定をオン

他にもあったかも。。思い出し次第追記します。