c# 필요하거나 새 보안 정책에 따라.Net에서 이메일을 보내는 방법?




smtp 서버에 보안 연결이 필요하거나 클라이언트가 인증되지 않았습니다. (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 과 같은 다른 라이브러리를 사용할 필요가 없습니다.

사용자를보다 잘 보호하기 위해 Gmail 및 기타 메일 제공 업체는 모든 Google 애플리케이션을 OAuth 2.0으로 업그레이드 할 것을 권장합니다.

System.Net.Mail 이 더 이상 작동하지 않고 MailKit 과 같은 다른 라이브러리를 사용해야한다는 것을 의미하는 것이 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. 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 사용하는 MailKit 이 질문은 System.Net.Mail 에서 MailKitGoogle.Apis.Auth.OAuth2 를 사용하는 데 유용한 단계별 자습서가 될 것입니다. 어쩌면 일반적인 솔루션은 DotNetOpenAuth 사용할 DotNetOpenAuth 입니까?

내 응용 프로그램에 어떤 주소 (gmail, yandex 및 기타)로 전자 메일을 보내는 데 해당하는 다음 클래스가 있습니다.

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.MailOAuth2 지원하지 않는다는 것을 안다. 나는 메시지를 보내기 위해 MailKit's SmtpClient 를 사용하기로 결정했다.

조사가 끝나면 MailKit's API가 System.Net.Mail 과 매우 유사하기 때문에 초기 코드가 그렇게 많이 변하지 않는다는 것을 이해합니다.

하나의 세부 사항 제외 : 사용자의 OAuth 액세스 토큰을 가져야합니다 (MailKit에는 OAuth 토큰을 가져 오는 코드가 없지만 가지고 있다면 사용할 수 있음).

그래서 앞으로 나는 다음과 같은 내용을 갖게 될 것이다 :

smtpClient.Authenticate (usersLoginName, usersOAuthToken);

SendEmail 메소드에 새로운 매개 변수로 GoogleCredentials 를 추가 할 생각이 있습니다.

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)


사용자를 얻는 방법은 무엇입니까?

가장 먼저해야 할 일은 애플리케이션에 대한 OAuth 2.0 자격증 명을 얻기위한 Google의 안내 를 따르는 것입니다.

일단 액세스 토큰을 얻는 가장 쉬운 방법은 Google의 Google.Apis.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 ("[email protected]") {
                    // Note: other scopes can be found here: https://developers.google.com/gmail/api/auth/scopes
                    Scopes = new[] { "https://mail.google.com/" },
                    User = "[email protected]"
                }.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", "[email protected]"));
            message.To.Add (new MailboxAddress ("Recipient's Name", "[email protected]"));
            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 ("[email protected]", credential.Token.AccessToken);

                client.Send (message);

                client.Disconnect (true);
            }
        }
    }
}

Google.Apis.Auth.OAuth2를 사용하는 것이 가장 좋은 방법입니까?

인증 토큰을 얻기 위해 API를 사용하지 않는 이유는 무엇입니까? 나에게 가져다주는 가장 좋은 방법 인 것 같아.

Gmail 계정이 아닌 다른 계정으로 이메일을 보낼 수 있습니까?

예, Gmail을 통해 보내는 모든 이메일은 다른 이메일 주소로 보낼 수 있습니다. 다른 Gmail 주소로만 전송할 필요는 없습니다.


Google의 특정 보안 요구 사항을 구현하지 않는 응용 프로그램에서 Gmail smtp 서버를 사용하면 인증 오류가 발생합니다. Gmail 계정 설정에서 '로그인 및 보안'> '연결된 앱 및 사이트'> '덜 안전한 앱 허용'> 사용 설정





.net