Как отправить in.net электронной почте в соответствии с новой политики безопасности?


чтобы лучше защитить своих пользователей, GMail и другие почтовые провайдеры рекомендуют обновить все наши приложения до OAuth 2.0.

я прав, что это означает, что System.Net.Mail больше не работают, и нам нужно использовать другую библиотеку, как MailKit?

в общем, я пытаюсь понять, как отправить электронное письмо, не разрешая "доступ для менее безопасных приложений"?

потому что у меня есть System.Net.Mail.SmtpException: The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.5.1 Authentication Required., когда smtpClient.Send(message); выполняется.

если единственный способ решить эту проблему можно с помощью MailKit, Я думаю, что этот вопрос будет хорошим практическим пошаговым руководством по переключению с System.Net.Mail С использованием MailKit и Google.Apis.Auth.OAuth2. Я не знаю, может быть, общее решение будет использовать DotNetOpenAuth?

у меня есть следующий класс в моем приложении, которые соответствуют отправьте письмо на любой адрес(Gmail, Яндекс и другие):

public class EmailSender
{
    public void SendEmail(SmtpServerSettings serverSettings, SendEmailRequest emailRequest)
    {
        // Usually I have 587 port, SmtpServerName = smtp.gmail.com 
        _logger.Trace("Sending message with subject '{0}' using SMTP server {1}:{2}",
                      emailRequest.Subject,
                      serverSettings.SmtpServerName,
                      serverSettings.SmtpPort);

        try
        {
            using (var smtpClient = new SmtpClient(serverSettings.SmtpServerName, (int)serverSettings.SmtpPort))
            {
                smtpClient.EnableSsl = serverSettings.SmtpUseSsl; // true
                if (!string.IsNullOrEmpty(serverSettings.UserName) || !string.IsNullOrEmpty(serverSettings.EncryptedPassword))
                {
                    smtpClient.Credentials = new NetworkCredential(serverSettings.UserName, serverSettings.EncryptedPassword);
                }

                smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;
                smtpClient.Timeout = (int)serverSettings.SmtpTimeout.TotalMilliseconds;

                using (var message = new MailMessage())
                {
                    message.From = new MailAddress(serverSettings.FromAddress);

                    emailRequest.To.ForEach(message.To.Add);
                    emailRequest.CC.ForEach(message.CC.Add);
                    emailRequest.Bcc.ForEach(message.Bcc.Add);

                    message.Subject = emailRequest.Subject.Replace('r', ' ').Replace('n', ' ');
                    message.Body = emailRequest.Body;
                    message.BodyEncoding = Encoding.UTF8;
                    message.IsBodyHtml = false;

                    smtpClient.Send(message);
                }
            }

            _logger.Trace("Sent message with subject '{0}' using SMTP server {1}:{2}",
                          emailRequest.Subject,
                          serverSettings.SmtpServerName,
                          serverSettings.SmtpPort);
        }
        catch (SmtpFailedRecipientsException e)
        {
            var failedRecipients = e.InnerExceptions.Select(x => x.FailedRecipient);
            LogAndReThrowWithValidMessage(e, EmailsLocalization.EmailDeliveryFailed, failedRecipients);
        }
   }
}

он работает новые политики безопасности Google.

я знаю это System.Net.Mail не поддерживает OAuth2. Я решил использовать MailKit'sSmtpClient для отправки сообщений.

после расследования я понимаю, что мой первоначальный код не изменится так сильно, потому что MailKit's API выглядит очень похоже(с System.Net.Mail).

кроме одной детали: мне нужно иметь маркер доступа OAuth пользователя (MailKit не имеет кода, который будет получать маркер OAuth, но он может использовать его, если он у меня есть).

так что в будущем у меня будет следующим линия:

smtpClient.Authenticate (usersLoginName, usersOAuthToken);

у меня есть идея, чтобы добавить GoogleCredentials как новый параметр SendEmail способ:

public void SendEmail(SmtpServerSettings serverSettings, SendEmailRequest emailRequest, 
                      GoogleCredentials credentials)
{
    var certificate = new X509Certificate2(credentials.CertificateFilePath,
                                           credentials.PrivateKey,
                                           X509KeyStorageFlags.Exportable);

     var credential = new ServiceAccountCredential(
                      new ServiceAccountCredential.Initializer(credentials.ServiceAccountEmail)
                             {
                                 Scopes = new[] { "https://mail.google.com/" },
                                 User = serverSettings.UserName
                             }.FromCertificate(certificate));

    ....
    //my previous code but with MailKit API
}

Как добраться usersOAuthToken? Это лучший метод практики для использования Google.Apis.Auth.OAuth2?

код, который я опубликовал выше, предназначен только для GMail и не будет работать yandex.ru или другие почтовые провайдеры. Чтобы работать с другими, мне, вероятно, придется использовать другую библиотеку OAuth2. Но я не хочу иметь много механизмов аутентификации в моем коде для многих возможных писем услуги поставщиков. Я хотел бы иметь одно общее решение для каждого почтового провайдера. И одна библиотека, которая может отправлять электронную почту (например, .net smtpclient)

3 64

3 ответа:

общее решение https://galleryserverpro.com/use-gmail-as-your-smtp-server-even-when-using-2-factor-authentication-2-step-verification/

1) с помощью браузера войдите в свой аккаунт Google и перейдите в Настройки входа и безопасности. Обратите внимание на 2-ступенчатую настройку проверки.

2) Если 2-шаговая проверка отключена, и вы хотите сохранить ее таким образом, это означает, что вам нужно будет реализовать много механизмов аутентификации, как вы сказал.

решение: включите его, а затем создать и использовать пароль приложения google. Это должно сработать! Вам не нужно использовать другие библиотеки, такие как mailkit.

Как получить usersOAuthToken?

первое, что вам нужно сделать, это следовать инструкции Google для получения учетных данных OAuth 2.0 для вашего приложения.

Как только вы это сделаете, самый простой способ получить маркер доступа-использовать Google Google.Апис.Auth библиотека:

using System;
using System.Threading;
using System.Security.Cryptography.X509Certificates;

using Google.Apis.Auth.OAuth2;

using MimeKit;
using MailKit.Net.Smtp;
using MailKit.Security;

namespace Example {
    class Program
    {
        public static async void Main (string[] args)
        {
            var certificate = new X509Certificate2 (@"C:\path\to\certificate.p12", "password", X509KeyStorageFlags.Exportable);
            var credential = new ServiceAccountCredential (new ServiceAccountCredential
                .Initializer ("your-developer-id@developer.gserviceaccount.com") {
                    // Note: other scopes can be found here: https://developers.google.com/gmail/api/auth/scopes
                    Scopes = new[] { "https://mail.google.com/" },
                    User = "username@gmail.com"
                }.FromCertificate (certificate));

            // Note: result will be true if the access token was received successfully
            bool result = await credential.RequestAccessTokenAsync (CancellationToken.None);

            if (!result) {
                Console.WriteLine ("Error fetching access token!");
                return;
            }

            var message = new MimeMessage ();
            message.From.Add (new MailboxAddress ("Your Name", "username@gmail.com"));
            message.To.Add (new MailboxAddress ("Recipient's Name", "recipient@yahoo.com"));
            message.Subject = "This is a test message";

            var builder = new BodyBuilder ();
            builder.TextBody = "This is the body of the message.";
            builder.Attachments.Add (@"C:\path\to\attachment");

            message.Body = builder.ToMessageBody ();

            using (var client = new SmtpClient ()) {
                client.Connect ("smtp.gmail.com", 587, SecureSocketOptions.StartTls);

                // use the access token as the password string
                client.Authenticate ("username@gmail.com", credential.Token.AccessToken);

                client.Send (message);

                client.Disconnect (true);
            }
        }
    }
}

Это лучший метод практики для использования Google.Апис.Автор.OAuth2?

почему бы и нет вы используете их API для получения маркера аутентификации? Кажется, это лучший способ получить его для меня...

смогу ли я отправлять электронные письма на другие учетные записи, а не на gmail?

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

ошибки аутентификации возникают при использовании smtp-сервера Gmail из приложений, не реализующих конкретные требования безопасности Google. В настройках учетной записи Gmail включите: "Вход и безопасность" > "Связанные приложения и сайты" > "Разрешить менее безопасные приложения" > На