2016-12-14 3 views
0

Ich versuche, eine E-Mail von einer Service Fabric Actor-Methode zu senden. Der Code ist sehr einfach und funktioniert ohne Problem in einer Konsolenanwendung, aber der gleiche Code innerhalb der Schauspieler Verfahren erzeugen die Ausnahme:
„Das Remote-Zertifikat ungültig ist nach dem Validierungsverfahren“E-Mail vom Service-Fabric-Actor mit SmtpClient senden schlägt fehl

Ich habe keine Ahnung, warum diese passiert und was ich meinem Code hinzufügen sollte, damit es funktioniert (ich möchte die Zertifikatsüberprüfung nicht umgehen oder die Verschlüsselung deaktivieren), also suche ich Hilfe in diesem Forum.

Danke

Hier ist mein Code (nur ersetzt Anmeldeinformationen und Domain mit Dummy-Namen)

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Net; 
using System.Net.Mail; 
using System.Text; 
using System.Threading.Tasks; 

namespace testsmtp { 
    class Program { 
     static void Main(string[] args) { 
     SendEmailAlert("myuserid", "mypassword", "[email protected]", "test subject", "test body"); 
     } 

     private static bool SendEmailAlert(string uid, string pwd, string recipient_list, string subject, string body) { 
     MailMessage msg = new MailMessage(); 
     msg.To.Add(recipient_list); 
     msg.From = new MailAddress("[email protected]"); 
     msg.Subject = subject; 
     msg.Body = body; 
     msg.IsBodyHtml = false; 
     SmtpClient client = new SmtpClient(); 
     client.Host = "smtp.mydomain.com"; 
     client.Port = 587; 
     client.EnableSsl = true; 
     client.UseDefaultCredentials = false; 
     client.Credentials = new NetworkCredential(uid, pwd); 
     try { 
      client.Send(msg); 
      return true; 
     } 
     catch (Exception e) { 
      string emsg = e.Source + "\n" + e.Message; 
      return false; 
     } 
     } 



    } 
} 

und hier ist die Ausnahmedaten

Message "The remote certificate is invalid according to the validation procedure." string 


    StackTrace " at System.Net.Security.SslState.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, Exception exception)\r\n at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)\r\n at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)\r\n at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)\r\n at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)\r\n at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)\r\n at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)\r\n at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)\r\n at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)\r\n at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)\r\n at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)\r\n at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)\r\n at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)\r\n at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)\r\n at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)\r\n at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)\r\n at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)\r\n at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)\r\n at System.Net.TlsStream.ProcessAuthentication(LazyAsyncResult result)\r\n at System.Net.TlsStream.Write(Byte[] buffer, Int32 offset, Int32 size)\r\n at System.Net.Mail.SmtpConnection.Flush()\r\n at System.Net.Mail.ReadLinesCommand.Send(SmtpConnection conn)\r\n at System.Net.Mail.EHelloCommand.Send(SmtpConnection conn, String domain)\r\n at System.Net.Mail.SmtpConnection.GetConnection(ServicePoint servicePoint)\r\n at System.Net.Mail.SmtpClient.GetConnection()\r\n at System.Net.Mail.SmtpClient.Send(MailMessage message)\r\n at UserActor.UserActor.DeliverFeedbackMessage(String cur_msg, String remote_ip, String usr_agent) in C:\\testsrc\\DigitalRadar\\UserActor\\UserActor.cs:line 621" string 

Antwort

0

Sie verwenden SSL Stellen Sie eine Verbindung zum Mail-Server her (smtp.mydomain.com). Überprüfen Sie, ob das Zertifikat auf dem Mailserver ein gültiges (CA signiertes) Zertifikat hat. Vielleicht ist es selbstsigniert oder abgelaufen oder hat eine schwache Chiffre.

+0

Danke, das ist nicht der Fall, ich persönlich, manuell überprüft das Server-Zertifikat und es ist perfekt, es ist ein azurblauer offizieller Partner BTW. Ich vermute einen Fehler in der SF-Akteur sdk, ich werde dies dem SF-Team melden. Inzwischen habe ich einen guten Workaround gefunden, um das Problem zu lösen und werde mein eigenes q beantworten. um anderen mit dem gleichen Problem zu helfen. Danke nochmal –

0

Alles klar, ich fand eine gute Problemumgehung (ohne Sicherheit zu gefährden), um dieses Problem zu vermeiden, beantworte ich meine eigene Frage, um jedem zu helfen, der das gleiche Problem haben könnte und hier endet.

Ich sollte erwähnen, meine SF-Version ist 5.0.217, Schauspieler ver 2.0.217 ist, vielleicht neuere ver. könnte das Problem nicht haben, da das SF-Team das Framework kontinuierlich verbessert. Wenn ich etwas Zeit habe, werde ich das neue ver überprüfen und diesen Thread für den Fall aktualisieren.

Zurück zum Problem scheint es, die Standard-CERT-Validierung schlägt fehl, wenn SmtpClient.Send aus einer SF-Actor-Methode aufgerufen wird. Der gleiche Anruf aus einer C# -Konsolen-App funktioniert großartig. Der Grund ist jenseits meines Verständnisses, vielleicht einige SF Glitch, sowieso. NET erlaubt schreiben und registrieren eine benutzerdefinierte Validierungsprozedur, um die Standard zu ersetzen, mit diesem Ansatz habe ich das Problem gelöst, aber es ist wichtig, nicht blind zu sagen "gültig" zu Zertifikat, wie ich in vielen upvoted Posts hier auf SO vorgeschlagen habe, empfehle ich, das Zertifikat zu überprüfen, um zu sehen, ob es gut ist, sonst schrauben Sie die Sicherheit, dann gibt es keinen Sinn, SSL oder Zertifikat überhaupt zu verwenden. Having said that, hier ist mein Validierungscode (Anpassung an Ihre eigene Situation)

private bool MyValidateSmtpServerCertificate(object sender, X509Certificate certificate, 
               X509Chain chain, SslPolicyErrors sslPolicyErrors) { 
     if (sslPolicyErrors != SslPolicyErrors.None) 
      return false; 
     string[] subj_params = certificate.Subject.Split(','); 
     string common_name = string.Empty; 
     foreach (string param in subj_params) { 
      string[] sub_params = param.Split('='); 
      if (sub_params[0].Trim() == "CN") 
       common_name = sub_params[1].Trim(); 
     } 
     string[] valid_names = { 
      common_const.smtpServer, 
      "*." + common_const.smtpServer, 
     }; 
     if (!valid_names.Contains(common_name)) 
      return false; 
     return true; 
     } 

Register dieser Funktion vor der SmtpClient.Send mit der folgenden Zeile Aufruf:

ServicePointManager.ServerCertificateValidationCallback = MyValidateSmtpServerCertificate; 

Das ist alles, jetzt Mein Code innerhalb der Actor-Methode funktioniert einwandfrei, die E-Mail wird sicher und zuverlässig zugestellt.

+0

können Sie den Wert von sslPolicyErrors posten? – LoekD

Verwandte Themen