2016-12-14 300 views
0

我試圖從服務結構角色方法發送電子郵件。該代碼是非常簡單的,沒有問題的工作在一個控制檯應用程序,但男主角方法中非常相同的代碼生成異常:
使用SmtpClient從服務結構角色發送電子郵件失敗

「的遠程證書根據驗證程序是無效的」我不知道爲什麼這個正在發生,我應該添加到我的代碼,使其工作(我不想繞過證書驗證或禁用加密),所以我在這個論壇上尋找幫助。

謝謝

這裏是我的代碼(剛剛更換憑證和域名與虛擬名稱)

​​

,這裏是異常數據

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 

回答

0

你使用SSL連接到郵件服務器(smtp.mydomain.com)。檢查郵件服務器上的證書是否有有效的(CA簽名)證書。也許它是自簽名的,或過期的,或者有一個弱密碼。

+0

謝謝,那不是,我個人,手動檢查服務器證書,它是完美的,這是一個天藍色的官方合作伙伴btw。 我懷疑SF演員sdk有一個小故障,我會向SF團隊彙報。同時我找到了一個很好的解決方法來解決問題,並會回答我自己的問題。幫助他人解決同樣的問題。再次感謝 –

0

好吧,我發現了一個很好的解決方法(不影響安全性)來避免這個問題,我正在回答我自己的問題以幫助任何可能有同樣問題並最終出現在這裏的人。

我應該提到我的SF版本是5.0.217,actors ver是2.0.217,也許更新版本。可能沒有問題,因爲SF團隊正在不斷改進框架。當我有一些時間,我會檢查新版本,並更新此線程以防萬一。

回到問題似乎默認證書驗證失敗時SmtpClient.Send從SF演員方法中調用。從C#控制檯應用程序進行的相同調用效果很好。原因超出了我的理解,也許一些SF故障,無論如何.NET允許編寫和註冊一個自定義驗證過程來取代默認的過程,使用這種方法我解決了這個問題,但重要的是不要盲目地說任何「有效」證書,正如我在SO上看到的許多積極的帖子中所建議的那樣,我建議實際檢查證書以查看證書是否正確,否則就會影響安全性,因此完全沒有必要使用SSL或證書。話雖如此,這裏是我的驗證代碼(使其適應自己的情況)

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

註冊調用SmtpClient.Send與下面的行之前此功能:

ServicePointManager.ServerCertificateValidationCallback = MyValidateSmtpServerCertificate; 

這一切,現在我的演員方法內的代碼完美地工作,電子郵件安全可靠地交付。

+0

你可以發佈sslPolicyErrors的值嗎? – LoekD

相關問題