it-swarm-vi.com

SmtpClient với Gmail

Tôi đang phát triển một ứng dụng thư cho một dự án trường học. Tôi đã quản lý để gửi e-mail bằng cách sử dụng SmtpClient trong C #. Điều này hoạt động hoàn hảo với bất kỳ máy chủ nào nhưng nó không hoạt động với Gmail. Tôi tin rằng đó là do Google sử dụng TLS. Tôi đã thử đặt EnableSsl thành true trên SmtpClient nhưng điều này không tạo ra sự khác biệt.

Đây là mã tôi đang sử dụng để tạo SmtpClient và gửi e-mail.

this.client = new SmtpClient("smtp.gmail.com", 587);
this.client.EnableSsl = true;
this.client.UseDefaultCredentials = false;
this.client.Credentials = new NetworkCredential("username", "password");

try
{
    // Create instance of message
    MailMessage message = new MailMessage();

    // Add receiver
    message.To.Add("[email protected]");

    // Set sender
    // In this case the same as the username
    message.From = new MailAddress("[email protected]");

    // Set subject
    message.Subject = "Test";

    // Set body of message
    message.Body = "En test besked";

    // Send the message
    this.client.Send(message);

    // Clean up
    message = null;
}
catch (Exception e)
{
    Console.WriteLine("Could not send e-mail. Exception caught: " + e);
}

Đây là lỗi tôi gặp phải khi tôi cố gắng gửi e-mail.

Could not send e-mail. Exception caught: System.Net.Mail.SmtpException: Message could not be sent. ---> System.IO.IOException: The authentication or decryption has failed. ---> System.InvalidOperationException: SSL authentication error: RemoteCertificateNotAvailable, RemoteCertificateChainErrors
  at System.Net.Mail.SmtpClient.<callback>m__4 (System.Object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Security.Cryptography.X509Certificates.X509Chain chain, SslPolicyErrors sslPolicyErrors) [0x00000] in <filename unknown>:0 
  at System.Net.Security.SslStream+<BeginAuthenticateAsClient>c__AnonStorey7.<>m__A (System.Security.Cryptography.X509Certificates.X509Certificate cert, System.Int32[] certErrors) [0x00000] in <filename unknown>:0 
  at Mono.Security.Protocol.Tls.SslClientStream.OnRemoteCertificateValidation (System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Int32[] errors) [0x00000] in <filename unknown>:0 
  at Mono.Security.Protocol.Tls.SslStreamBase.RaiseRemoteCertificateValidation (System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Int32[] errors) [0x00000] in <filename unknown>:0 
  at Mono.Security.Protocol.Tls.SslClientStream.RaiseServerCertificateValidation (System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Int32[] certificateErrors) [0x00000] in <filename unknown>:0 
  at Mono.Security.Protocol.Tls.Handshake.Client.TlsServerCertificate.validateCertificates (Mono.Security.X509.X509CertificateCollection certificates) [0x00000] in <filename unknown>:0 
  at Mono.Security.Protocol.Tls.Handshake.Client.TlsServerCertificate.ProcessAsTls1 () [0x00000] in <filename unknown>:0 
  at Mono.Security.Protocol.Tls.Handshake.HandshakeMessage.Process () [0x00000] in <filename unknown>:0 
  at (wrapper remoting-invoke-with-check) Mono.Security.Protocol.Tls.Handshake.HandshakeMessage:Process ()
  at Mono.Security.Protocol.Tls.ClientRecordProtocol.ProcessHandshakeMessage (Mono.Security.Protocol.Tls.TlsStream handMsg) [0x00000] in <filename unknown>:0 
  at Mono.Security.Protocol.Tls.RecordProtocol.InternalReceiveRecordCallback (IAsyncResult asyncResult) [0x00000] in <filename unknown>:0 
  --- End of inner exception stack trace ---
  at Mono.Security.Protocol.Tls.SslStreamBase.AsyncHandshakeCallback (IAsyncResult asyncResult) [0x00000] in <filename unknown>:0 
  --- End of inner exception stack trace ---
  at System.Net.Mail.SmtpClient.Send (System.Net.Mail.MailMessage message) [0x00000] in <filename unknown>:0 
  at P2Mailclient.SMTPClient.send (P2Mailclient.Email email) [0x00089] in /path/to/my/project/SMTPClient.cs:57 

Có ai có ý tưởng tại sao tôi có thể nhận được lỗi này?

30
simonbs

Hãy thử chạy nó:

mozroots --import --ask-remove

trong hệ thống của bạn (chỉ trong bash hoặc từ Mono Command Prompt nếu nó có trên Windows). Và sau đó chạy lại mã.

CHỈNH SỬA:

Tôi quên bạn cũng nên chạy

certmgr -ssl smtps://smtp.gmail.com:465

(và trả lời có cho câu hỏi). Điều này hoạt động với tôi trên Mono 2.10.8, Linux (với ví dụ của bạn).

22
konrad.kruczynski

Máy chủ SMTP của Gmail yêu cầu bạn xác thực yêu cầu của mình bằng kết hợp email/mật khẩu gmail hợp lệ. Bạn cũng cần kích hoạt SSL. Không thực sự có thể thấy một bãi chứa tất cả các biến của bạn được thông qua theo phỏng đoán tốt nhất tôi có thể đưa ra là Thông tin xác thực của bạn không hợp lệ, hãy đảm bảo bạn đang sử dụng hợp lệ GMAIL kết hợp email/mật khẩu.

Bạn có thể muốn đọc ở đây cho một ví dụ hoạt động.

EDIT: Được rồi đây là thứ tôi đã viết và thử nghiệm ngay sau đó và nó hoạt động tốt với tôi:

public static bool SendGmail(string subject, string content, string[] recipients, string from) {
    if (recipients == null || recipients.Length == 0)
        throw new ArgumentException("recipients");

    var gmailClient = new System.Net.Mail.SmtpClient {
        Host = "smtp.gmail.com",
        Port = 587,
        EnableSsl = true,
        UseDefaultCredentials = false,
        Credentials = new System.Net.NetworkCredential("******", "*****")
    };

    using (var msg = new System.Net.Mail.MailMessage(from, recipients[0], subject, content)) {
        for (int i = 1; i < recipients.Length; i++)
            msg.To.Add(recipients[i]);

        try {
            gmailClient.Send(msg);
            return true;
        }
        catch (Exception) {
            // TODO: Handle the exception
            return false;
        }
    }
}

Nếu bạn cần thêm thông tin, có một bài báo SO tương tự tại đây

23
Jason Larke

Tôi nghĩ rằng, bạn cần xác thực chứng chỉ máy chủ được sử dụng để thiết lập các kết nối SSL .....

Sử dụng mã sau để gửi thư có chứng chỉ máy chủ xác thực .....

            this.client = new SmtpClient(_account.SmtpHost, _account.SmtpPort);
            this.client.EnableSsl = _account.SmtpUseSSL;
            this.client.Credentials = new NetworkCredential(_account.Username, _account.Password);

        try
        {
            // Create instance of message
            MailMessage message = new MailMessage();

            // Add receivers
            for (int i = 0; i < email.Receivers.Count; i++)
                message.To.Add(email.Receivers[i]);

            // Set sender
            message.From = new MailAddress(email.Sender);

            // Set subject
            message.Subject = email.Subject;

            // Send e-mail in HTML
            message.IsBodyHtml = email.IsBodyHtml;

            // Set body of message
            message.Body = email.Message;

            //validate the certificate
            ServicePointManager.ServerCertificateValidationCallback =
            delegate(object s, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
            { return true; };


            // Send the message
            this.client.Send(message);

            // Clean up
            message = null;
        }
        catch (Exception e)
        {
            Console.WriteLine("Could not send e-mail. Exception caught: " + e);
        }

Nhập không gian tên System.Security.Cryptography.X509Certificates để sử dụng ServicePointManager

4
user1082916

Mã này hoạt động tốt với tôi, thử dán mã này vào LinqPad, chỉnh sửa địa chỉ thư và mật khẩu và cho chúng tôi biết những gì bạn thấy:

var client = new System.Net.Mail.SmtpClient("smtp.gmail.com", 587);
client.EnableSsl = true;
client.UseDefaultCredentials = false;
client.Credentials = new System.Net.NetworkCredential("[email protected]", "xxxxxxx");

try
{
    // Create instance of message
    System.Net.Mail.MailMessage message = new System.Net.Mail.MailMessage();

    // Add receiver
    message.To.Add("[email protected]");

    // Set sender
    // In this case the same as the username
    message.From = new System.Net.Mail.MailAddress("[email protected]");

    // Set subject
    message.Subject = "Test";

    // Set body of message
    message.Body = "En test besked";

    // Send the message
    client.Send(message);

    // Clean up
    message = null;
}
catch (Exception e)
{
    Console.WriteLine("Could not send e-mail. Exception caught: " + e);
}
3
rasmusvhansen

Bạn cần bật Xác minh 2 bước trong tài khoản gmail của mình và tạo mật khẩu ứng dụng ( https://support.google.com/accountsals/185833?hl=vi ). Khi bạn thay thế mật khẩu của mình bằng mật khẩu ứng dụng mới, nó sẽ hoạt động.

Credentials = new System.Net.NetworkCredential("your email address", "your app password");
3
Poet

Tôi bắt đầu nhận được điều này với GMail vào tháng 5 năm 2013 sau khi làm việc được 6 tháng. Dự án Mono Sử dụng Rễ đáng tin cậy tài liệu cung cấp hướng dẫn về công việc xung quanh. Tôi đã chọn tùy chọn # 1:

ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

Thật quá quấy rầy khi có e-mail cho dịch vụ của tôi ngừng hoạt động mà không có cảnh báo.

Cập nhật ngày 26 tháng 8 năm 2016: người dùng Chico đã đề xuất triển khai hoàn tất cuộc gọi lại ServerCertertValidationCallback sau đây. Tôi chưa thử.

ServicePointManager.ServerCertificateValidationCallback = MyRemoteCertificateValidationCallback;

bool MyRemoteCertificateValidationCallback(System.Object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) {
    bool isOk = true;
    // If there are errors in the certificate chain, look at each error to determine the cause.
    if (sslPolicyErrors != SslPolicyErrors.None) {
        for (int i=0; i<chain.ChainStatus.Length; i++) {
            if (chain.ChainStatus [i].Status != X509ChainStatusFlags.RevocationStatusUnknown) {
                chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain;
                chain.ChainPolicy.RevocationMode = X509RevocationMode.Online;
                chain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan (0, 1, 0);
                chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllFlags;
                bool chainIsValid = chain.Build ((X509Certificate2)certificate);
                if (!chainIsValid) {
                    isOk = false;
                }
            }
        }
    }
    return isOk;

}
1
t9mike