it-swarm-id.com

SmtpClient dengan Gmail

Saya sedang mengembangkan klien email untuk proyek sekolah. Saya telah berhasil mengirim email menggunakan SmtpClient di C #. Ini berfungsi sempurna dengan server mana pun tetapi tidak bekerja dengan Gmail. Saya percaya itu karena Google menggunakan TLS. Saya telah mencoba mengatur EnableSsl ke true pada SmtpClient tetapi ini tidak membuat perbedaan.

Ini adalah kode yang saya gunakan untuk membuat SmtpClient dan mengirim email.

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);
}

Ini adalah kesalahan yang saya dapatkan ketika saya mencoba mengirim email.

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 

Adakah yang tahu mengapa saya mendapatkan kesalahan ini?

30
simonbs

Coba jalankan ini:

mozroots --import --ask-remove

di sistem Anda (hanya di bash atau dari Mono Command Prompt jika ada di Windows). Dan kemudian jalankan kodenya lagi.

EDIT:

Saya lupa Anda juga harus lari

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

(dan jawab ya pada pertanyaan). Ini berfungsi untuk saya di Mono 2.10.8, Linux (dengan contoh Anda).

22

Server SMTP Gmail mengharuskan Anda untuk mengotentikasi permintaan Anda dengan kombinasi email/kata sandi gmail yang valid. Anda juga perlu mengaktifkan SSL. Tanpa benar-benar dapat melihat dump semua variabel Anda diteruskan dalam tebakan terbaik yang dapat saya buat adalah bahwa Kredensial Anda tidak valid, pastikan Anda menggunakan valid GMAIL kombinasi email/kata sandi.

Anda mungkin ingin membaca sini untuk contoh yang berfungsi.

EDIT: Oke, inilah sesuatu yang saya tulis dan uji saat itu dan itu bekerja dengan baik untuk saya:

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

Jika Anda memerlukan info lebih lanjut, ada artikel SO serupa di sini

23
Jason Larke

Saya pikir, Anda perlu memvalidasi sertifikat server yang digunakan untuk membuat koneksi SSL .....

Gunakan kode berikut untuk mengirim surat dengan sertifikat server yang valid .....

            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);
        }

Impor namespace System.Security.Cryptography.X509Certificates untuk menggunakan ServicePointManager

4
user1082916

Kode ini berfungsi dengan baik untuk saya, coba tempelkan ini ke LinqPad, edit alamat email dan kata sandi dan beri tahu kami apa yang Anda lihat:

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

Anda perlu mengaktifkan Verifikasi 2 Langkah di akun gmail Anda dan membuat kata sandi aplikasi ( https://support.google.com/accounts/answer/185833?hl=id ). Setelah Anda mengganti kata sandi dengan kata sandi aplikasi yang baru, itu akan berfungsi.

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

Saya mulai mendapatkan ini dengan GMail pada Mei 2013 setelah bekerja selama 6 momths. Proyek Mono Menggunakan Roots Tepercaya dengan Hormat dokumen memberikan panduan untuk bekerja di sekitar. Saya memilih opsi # 1:

ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

Terlalu mengganggu untuk memiliki e-mail agar layanan saya berhenti bekerja tanpa peringatan.

Pembaruan 26 Agustus 2016: pengguna Chico menyarankan implementasi lengkap panggilan balik ServerCertificateValidationCallback berikut. Saya belum diuji.

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