web-dev-qa-db-ja.com

Office365でデフォルトのSMTP資格情報を使用する例外-MAIL FROM中に匿名メールを送信するためにクライアントが認証されませんでした

NLogを使用して、カスタムメールターゲットを含む電子メールとしてログを送信しています。次のように、(メインプロジェクトの)web.configでデフォルトとして設定されたoffice365アカウントから送信しています。

  <system.net>
    <mailSettings>
      <smtp deliveryMethod="Network" from="[email protected]">
        <network defaultCredentials="false" Host="smtp.office365.com" port="587" userName="[email protected]" password="mypassword" enableSsl="true" />
      </smtp>
    </mailSettings>
  </system.net>

次のように、(NLog実装パッケージ内の)ログターゲットでWriteメソッドをオーバーライドします。

    protected override void Write(LogEventInfo logEvent) 
    { 
        try
        {
            using (var mail = new MailMessage())
            {
                this.SetupMailMessage(mail, logEvent, this.Layout.Render(logEvent));

                using (SmtpClient smtpClient = new SmtpClient())
                {
                    smtpClient.UseDefaultCredentials = true;
                    smtpClient.Send(mail);
                }
            }
        }
        catch (Exception exception)
        {
            throw new NLogRuntimeException("An error occurred when sending a log mail message.", exception);
        }
    }

システムがこのアカウントからメールを送信しようとすると、次のSystem.Net.Mail.SmtpExceptionがスローされます。

SMTPサーバーに安全な接続が必要であるか、クライアントが認証されていません。サーバーの応答は5.7.57 SMTP;クライアントは、MAIL FROM中に匿名メールを送信するために認証されませんでした

資格情報を4回確認しましたが、正しいです。誰もこの例外を引き起こす可能性のあるものを知っていますか?

PDATE: CredentialCache.DefaultCredentialsプロパティは空の文字列で一杯です。ただし、以下のコードを使用して設定を手動で抽出すると、web.configから設定を取得できます。

SmtpSection settings = (SmtpSection)ConfigurationManager.GetSection("system.net/mailSettings/smtp");
smtpClient.Credentials = new NetworkCredential(settings.Network.UserName, settings.Network.Password);
smtpClient.Host = settings.Network.Host;
smtpClient.Port = settings.Network.Port;
smtpClient.EnableSsl = settings.Network.EnableSsl;

var creds = CredentialCache.DefaultCredentials;  // Is empty

これを回避策として使用できます。しかし、何が得られますか?デフォルトの資格情報が空になるのはなぜですか?

11
Ivan

回答の更新で言及した回避策は機能しましたが、これらの値を手動で取得することに満足していませんでした。私にとっての解決策は、行を削除する

smtpClient.UseDefaultCredentials = true;

私が投稿した元のコードから。 smtpClientはweb.configで設定したデフォルトの資格情報で初期化され、上記の削除された行はCredentialCache.DefaultCredentialsからの空の文字列で上書きされていました。 CredentialCache.DefaultCredentialsが空である理由、またはweb.configからデータが入力されることになっている理由はまだわかりませんが、これが問題の原因でした。

誰かがこれについてさらに洞察を持っている場合は、より良い答えを投稿してください!

7
Ivan

この投稿のおかげで、私たちの問題を解決することができました。 RackspaceのハイブリッドセットアップからメールボックスをO365に移行しました。送信に使用されていたメールボックスは、以前はExchangeアカウントではありませんでしたが、移行後にアカウントになりました。

mySmtpClient = New SmtpClient("smtp.office365.com")
mySmtpClient.Port = 587
mySmtpClient.EnableSsl = True
mySmtpClient.Credentials = New System.Net.NetworkCredential("[email protected]", "password", "domain.com")
mySmtpClient.Send(Msg)

以前のセットアップでは、ポートを提供したり、sslを有効にしたり、資格情報パラメーターにドメインを入れたりする必要もありませんでした。これが、VB Office 365でSMTPを介した電子メールを自動化するスクリプトで作業する必要のある人々に役立つことを願っています。

10
Pawr

サードパーティのホスティングプロバイダーでこの統合を行う場合、ドメイン名も提供する必要があります。

SmtpClient client = new SmtpClient(SMTPSettings.Url, SMTPSettings.Port);
client.Credentials = new System.Net.NetworkCredential(SMTPSettings.UserName, SMTPSettings.Password, SMTPSettings.Domain);
1
ozkary

私は同じ問題を抱えていました、それが私のために働いたのは、System.Security.SecureStringを使用して文字列の代わりにパスワードを置くことでした、例:

        System.Security.SecureString psw = new System.Security.SecureString();

        string PasswordGmail = "XXXXXX";

        foreach (char item in PasswordGmail.ToCharArray())
        {
            psw.AppendChar(item);
        }

        client.Credentials = new System.Net.NetworkCredential("[email protected]", psw); 
0
Luis Adrian