16

私の MVC4 アプリケーションでは、 を使用して、SmtpClientGmail のsmtp.gmail.comSMTP サーバー経由で電子メールを送信しています。

次の設定で Web.Config ファイルを構成しました。

<system.net>
 <mailSettings>
  <smtp deliveryMethod="Network">
   <network enableSsl="true" 
   defaultCredentials="false" 
   host="smtp.gmail.com" 
   port="587" 
   userName="xxMyUserNamexx@gmail.com" 
   password="xxMyPasswordxx" />
  </smtp>
 </mailSettings>
</system.net>

SmtpClient を使用して電子メール メッセージを送信するメソッドは次のようになります。

public void SendMail(string fromDisplayName, string fromEmailAddress, string toEmailAddress, string subject, string body)
{
    MailAddress from = new MailAddress(fromEmailAddress, fromDisplayName);
    MailAddress to = new MailAddress(toEmailAddress);
    MailMessage mailMessage = new MailMessage(from, to);
    mailMessage.Body = body;
    mailMessage.Subject = subject;

    SmtpClient client = new SmtpClient();
    //client.UseDefaultCredentials = false;
    client.Send(mailMessage);
}

上記のコードは期待どおりに機能し、問題ありません。私を混乱させているのは、コメント行ですclient.UseDefaultCredentials = false;。その行のコメントを外すと、次のような例外メッセージが表示されます。

SMTP サーバーが安全な接続を必要としているか、クライアントが認証されていません。サーバーの応答は次のとおりです。5.5.1 認証が必要です。

UseDefaultCredentialsさらに、プロパティをtrueまたはに設定しても問題ありませんfalse。それでも例外メッセージが表示されます。例外メッセージを回避する唯一の方法は、行を完全に削除することです。

この動作は正常ですか?例外メッセージが表示される理由を説明できますか?

4

4 に答える 4

26

では、なぜプロパティを明示的にfalseに設定すると、例外がスローされるのでしょうか。

これは、のセッターがfalseに設定した場合はプロパティをnullにUseDefaultCredentials設定し、trueに設定した場合はプロパティに設定するためです。このプロパティは、MSDNによって次のように定義されています。CredentialsCredentialCache.DefaultNetworkCredentialsDefaultNetworkCredentials

DefaultNetworkCredentialsによって返されるクレデンシャルは、アプリケーションが実行されている現在のセキュリティコンテキストの認証クレデンシャルを表します。クライアント側アプリケーションの場合、これらは通常、アプリケーションを実行しているユーザーのWindowsクレデンシャル(ユーザー名、パスワード、およびドメイン)です。ASP.NETアプリケーションの場合、デフォルトのネットワーククレデンシャルは、ログインしているユーザーまたは偽装されているユーザーのユーザークレデンシャルです。

trueに設定UseDefaultCredentialsすると、IISユーザーが使用されます。また、IISユーザーは、使用しているSMTPサーバーのアカウントと同じ認証資格情報を持っていないと想定しています。UseDefaultCredentialsfalse nullに設定すると、設定されているクレデンシャルが削除されます。したがって、どちらの方法でも、そのエラーが発生します。

dotPeekUseDefaultCredentialsを使用するためのセッターを見てみましょう。

set
{
    if (this.InCall)
    {
        throw new InvalidOperationException(
            SR.GetString("SmtpInvalidOperationDuringSend"));
    }
    this.transport.Credentials = value 
        ? (ICredentialsByHost) CredentialCache.DefaultNetworkCredentials 
        : (ICredentialsByHost) null;
  }
于 2013-01-02T22:29:51.853 に答える
16

私は同じメッセージを受け取り、気が狂いそうになりました。このスレッドを読んだ後、資格情報の設定には順序が重要であることに気付きました。これはうまくいきました:

client.UseDefaultCredentials = false;
client.Credentials = new NetworkCredential(smtpSettings.Username, smtpSettings.Password);

これにより、あなたが説明したエラーが生成されました:

client.Credentials = new NetworkCredential(smtpSettings.Username, smtpSettings.Password);
client.UseDefaultCredentials = false;

これは、同じ問題を抱えている他の人への参考情報です。

于 2013-03-01T17:10:04.053 に答える
0

このオプションは、現在ログインしているユーザーのデフォルトの資格情報を使用するようにクライアントを設定します

true に設定すると、ユーザーの資格情報を使用しようとします。false に設定すると、クライアントの Credentials プロパティに明示的に設定された値が使用され、明示的に設定されていない場合は、ご覧のように匿名で接続しようとします。

于 2012-08-28T21:55:27.557 に答える