7

I'm trying to send e-mails through a domain SMTP server which uses Integrated Windows Authentication. When explicitly specifying the credentials, everything works fine:

using (var client = new SmtpClient("<Server>"))
{
    client.Credentials = new NetworkCredential("<User name>", "<Password>");
    client.EnableSsl = true;
    client.Send(...);
}

SMTP server logs show EHLO, STARTTLS, STARTTLS and EHLO, then AUTH, MAIL, etc.

When, on the other hand, default credentials are used:

using (var client = new SmtpClient("<Server>"))
{
    client.UseDefaultCredentials = true;
    client.EnableSsl = true;
    client.Send(...);
}
  • the SmtpException is thrown, with a message “Failure sending mail.”;

  • the inner IOException message is: “Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.”, and

  • the inner-inner SocketException is: “An existing connection was forcibly closed by the remote host”.

SMTP server logs show EHLO, STARTTLS, STARTTLS and EHLO, then nothing.

The result is exactly the same (success for the first sample, failure for the second one) if the options are moved from source code to App.config configuration/system.net/mailSettings/smtp/network, and whenever the port number is specified or not.

Given that:

  • according to the documentation, SmtpClient.UseDefaultCredentials “[g]ets or sets a Boolean value that controls whether the DefaultCredentials are sent with requests”, that

  • “For a client-side application, [CredentialCache.DefaultCredentials] are usually the Windows credentials (user name, password, and domain) of the user running the application”, and that

  • the tested code is a Windows Forms client-side application running from the same account whose credentials were specified in the first sample above,

why the second sample fails, while the first one works?


On a forum it was suggested that the issue may be cause by SMTP server not supporting NTLM. By EHLOing the server, it appears that NTLM is supported, one of the response lines being 250-AUTH GSSAPI NTLM.

Arseni Mourzenko
  • 50,338
  • 35
  • 112
  • 199

2 Answers2

11

If UseDefaultCredentials is set to true, it does NOT mean use the values in the Credentials property. It means use the credentials of the "currently logged on user", which in the case of IIS web apps will usually be the app pool identity, and in the case of a Windows service is the identity of the service, and in the case of a desktop application, it's the identity of the user logged into Windows.

If UseDefaultCredentials is false (the default), the Credentials property will be used if that property has a value set, otherwise mail will be sent anonymously.

See the Microsoft document https://msdn.microsoft.com/en-us/library/system.net.mail.smtpclient.usedefaultcredentials(v=vs.110).aspx (in the Remarks section).

Gen1-1
  • 424
  • 5
  • 9
6

I think you actually have to specify the Credentials as well. The UseDefaultCredentials is mere a flag telling the SMTPClient to use the Credentials provided to the Credentials property.

client.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;

Here's some other things to try:

Magnus Johansson
  • 28,010
  • 19
  • 106
  • 164
  • that makes sense because Credentials may be set to null if you don't do that – BumbleB2na Jun 06 '12 at 16:04
  • It helps. Partially. Now a new exception is thrown: “The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.7.3 Client was not authenticated.” – Arseni Mourzenko Jun 06 '12 at 16:23
  • Have you specified EnableSsl ? – Magnus Johansson Jun 06 '12 at 16:25
  • @Magnus - What are the credentials provided by SmtpClient.UseDefaultCredentials ? Where do they come from ? – Steam Jan 04 '14 at 00:51
  • 1
    @blasto the SmtpClient does not provide any credentials. The UseDefaultCredentials is a simple boolean to tell the SmtpClient class to use the credentials you provide to it. You provide the credentials by assigning them to the .Credentials property, as shown in my answer. In my example I'm simply providing the default network credentials, but you could also do an explicit assignment, such as client.Credentials = new NetworkCredential(username, password) – Magnus Johansson Jan 04 '14 at 20:22