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?
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).
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
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
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);
}
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");
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;
}