在Azure角色中使用SmtpClient时,“不支持请求的功能”异常

时间:2013-06-28 18:26:46

标签: c# .net azure smtpclient

在Azure Web或Worker角色中使用SmtpClient时出现异常。

我创建了一个控制台应用程序,通过RDP手动在角色VM上运行以重现:

using System;
using System.Net;
using System.Net.Mail;
using System.Text;

namespace ConsoleApplication1
{
   class Program
   {
      static void Main()
      {
         var mailClient = new SmtpClient("mail.redacted.com", 587);
         mailClient.EnableSsl = true;
         mailClient.DeliveryFormat = SmtpDeliveryFormat.International;
         mailClient.DeliveryMethod = SmtpDeliveryMethod.Network;

         mailClient.UseDefaultCredentials = false;//SET THIS FIRST OR IT WIPES OUT CREDENTIALS
         NetworkCredential netCreds = new NetworkCredential("mail@redacted.com", "12345 same combination on my luggage");
         mailClient.Credentials = netCreds;

         MailMessage message = new MailMessage();
         message.SubjectEncoding = Encoding.UTF8;
         message.BodyEncoding = Encoding.UTF8;
         message.IsBodyHtml = false;

         message.From = new MailAddress("mike@redacted.com");
         message.To.Add(new MailAddress("mike@redacted.com"));

         message.Subject = "testing " + DateTime.UtcNow;
         message.Body = "The quick brown fox jumped over the lazy dogs.";

         mailClient.Send(message);
      }
   }
}

本地发送电子邮件就好了。在Azure上,我得到了这个:

    Unhandled Exception: System.Net.Mail.SmtpException: Failure sending mail. ---> System.ComponentModel.Win32Exception: The function requested is not supported
       at System.Net.NTAuthentication.GetOutgoingBlob(Byte[] incomingBlob, Boolean throwOnError, SecurityStatus& statusCode)
       at System.Net.NTAuthentication.GetOutgoingBlob(String incomingBlob)
       at System.Net.Mail.SmtpNtlmAuthenticationModule.Authenticate(String challenge, NetworkCredential credential, Object sessionCookie, String spn, ChannelBinding channelBindingToken)
       at System.Net.Mail.SmtpConnection.GetConnection(ServicePoint servicePoint)
       at System.Net.Mail.SmtpClient.Send(MailMessage message)
       --- End of inner exception stack trace ---
       at System.Net.Mail.SmtpClient.Send(MailMessage message)
       at ConsoleApplication1.Program.Main() in c:\development\ConsoleApplication1\ConsoleApplication1\Program.cs:line 39

我已确认Azure计算机可以通过RDP在Azure角色上运行TCPing.exe来访问邮件服务器上的端口587。

1 个答案:

答案 0 :(得分:5)

显然问题是服务器之间的NTLM版本不匹配。

登录Azure角色并为客户端禁用“需要NTLMv2安全性”设置后,它才有效:

enter image description here

(感谢this answerthis answer的灵感。)

目前看看我们是否可以将我们的SMTP服务器升级为与NTLMv2兼容。否则,我们必须设置一些自动代码,以某种方式在每个生成的角色实例上禁用该设置。

显然这个代码上个月有效。所以我猜测最近的Azure OS升级改变了默认设置。

仅供参考:此设置的注册表项为

  

[HKEY_LOCAL_MACHINE \ SYSTEM \ CURRENTCONTROLSET \控制\ LSA \ MSV1_0]   “NtlmMinClientSec”= DWORD:20000000

要自动设置包含reg add命令的注册表项add a startup task,如下所示:

reg add HKLM\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0 ^
 /v NtlmMinClientSec ^
 /t REG_DWORD ^
 /d 0x20000000 ^
 /f

其中/f强制覆盖当前设置,^只允许将命令分成多行以提高可读性。另外,请确保以ASCII编码保存命令以防止issues during role startup