Je développe un client de messagerie pour un projet d'école. J'ai réussi à envoyer des courriels en utilisant la variable SmtpClient
en C #. Cela fonctionne parfaitement avec n'importe quel serveur, mais pas avec Gmail. Je crois que c'est à cause de l'utilisation de TLS par Google. J'ai essayé de régler EnableSsl
à true
sur SmtpClient
mais cela ne change rien.
C’est le code que j’utilise pour créer la variable SmtpClient
et envoyer un courrier électronique.
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);
}
C'est l'erreur que je reçois lorsque j'essaie d'envoyer un courrier électronique.
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
Quelqu'un at-il une idée de la raison pour laquelle je risque d’obtenir cette erreur?
Essayez de lancer ceci:
mozroots --import --ask-remove
dans votre système (uniquement en bash ou à partir de l'invite de commande mono s'il est sous Windows) Et puis exécutez le code à nouveau.
MODIFIER:
J'ai oublié que tu devrais aussi courir
certmgr -ssl smtps://smtp.gmail.com:465
(et répondez oui aux questions). Cela fonctionne pour moi sur Mono 2.10.8, Linux (avec votre exemple).
Le serveur SMTP de Gmail nécessite que vous authentifiiez votre demande avec une combinaison valide d'adresse e-mail/mot de passe Gmail. Vous devez également activer SSL. Sans être en mesure de voir toutes vos variables passées dans la meilleure hypothèse que je puisse faire, c’est que vos informations d’identité ne sont pas valides. Assurez-vous d’utiliser un code valide. GMAIL combinaison email/mot de passe.
Vous voudrez peut-être lire ici pour un exemple de travail.
EDIT: Ok, voici quelque chose que j'ai écrit et testé à ce moment-là et qui a bien fonctionné pour moi:
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;
}
}
}
Si vous avez besoin de plus d’informations, voici un article similaire SO ici
Je pense que vous devez valider le certificat de serveur utilisé pour établir les connexions SSL .....
Utilisez le code suivant pour envoyer un courrier électronique avec un certificat de serveur de validation .....
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);
}
Importer l'espace de noms System.Security.Cryptography.X509Certificates
à utiliser ServicePointManager
Ce code fonctionne très bien pour moi. Essayez de le coller dans LinqPad, modifiez les adresses e-mail et le mot de passe et dites-nous ce que vous voyez:
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);
}
Vous devez activer la vérification en deux étapes dans votre compte gmail et créer un mot de passe pour l'application ( https://support.google.com/accounts/answer/185833?hl=fr ). Une fois que vous avez remplacé votre mot de passe par le nouveau mot de passe de l'application, cela devrait fonctionner.
Credentials = new System.Net.NetworkCredential("your email address", "your app password");
J'ai commencé à recevoir cela avec GMail en mai 2013 après avoir travaillé pendant 6 mois. Le projet Mono Using Trusted Roots Respect Respect document fournit des indications sur la manière de contourner le problème. J'ai choisi l'option n ° 1:
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
Il est trop perturbant de voir un courrier électronique pour mon service cesser de fonctionner sans avertissement.
Mise à jour du 26 août 2016: l'utilisateur Chico a suggéré la mise en œuvre complète suivante du rappel ServerCertificateValidationCallback. Je n'ai pas testé.
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;
}