it-swarm.com.ru

Исключение при использовании учетных данных SMTP по умолчанию в Office365 - клиент не прошел проверку подлинности для отправки анонимной почты во время MAIL FROM

Я использую NLog для отправки журналов в виде электронной почты с настраиваемой почтовой целью. Я отправляю из моей учетной записи office365, настроенной по умолчанию в моем файле web.config (моего основного проекта), следующим образом:

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

Я перезаписываю метод Write своей целью журнала (в моем пакете реализации NLog) следующим образом:

    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; Клиент не прошел проверку подлинности для отправки анонимной почты во время ПОЧТЫ ОТ

Я четыре раза проверил учетные данные, и они верны. Кто-нибудь знает, что еще может быть причиной этого исключения?

ОБНОВЛЕНИЕ: Оказывается, свойство 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

Благодаря этому посту я смог решить наши проблемы. Мы перенесли почтовые ящики в O365 из гибридной установки в Rackspace. Почтовый ящик, который использовался для отправки, ранее не был учетной записью 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, автоматизирующими электронную почту через SMTP с Office 365.

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