【问题标题】:Sending Authenticated SMTP Using C#使用 C# 发送经过身份验证的 SMTP
【发布时间】:2011-12-22 01:25:32
【问题描述】:

我已通过我的托管公司购买了经过身份验证的 SMTP 包。

我已成功通过 Outlook 2010 测试了帐户设置。

Outlook 设置:

电子邮件:me@domain.com 外发 SMTP:smtp.hostingcompany.net

登录信息:

  • 用户:mydomain.com_account
  • pass:密码

更多设置>发送服务器:

  • 我的发送服务器 (SMTP) 需要身份验证
  • 用户:我的域
  • 密码:密码

我在指定 NetworkCredentials 时尝试了所有可能的组合,但我不断收到 SMTP 异常:“Faulure Sending Email” InnerException:Base-64 字符数组的长度无效。

public static void SendEmail(string To, string Subject, string Body)
    {
        try
        {
            using (SmtpClient mySmtpClient = new SmtpClient(GlobalSettings.EmailHost))
            {
                mySmtpClient.UseDefaultCredentials = false;
                //mySmtpClient.EnableSsl = false;
                mySmtpClient.Credentials = new NetworkCredential(mydomain.com_account, GlobalSettings.EmailPassword);

                MailAddress from = new MailAddress("email@mydomain");
                MailAddress to = new MailAddress(To);

                using (
                    MailMessage myMail = new MailMessage(from, to)
                    {
                        Subject = Subject,
                        SubjectEncoding = Encoding.UTF8,
                        Body = Body,
                        BodyEncoding = Encoding.UTF8,
                        IsBodyHtml = true
                    })
                {
                    mySmtpClient.Send(myMail);
                }
            }
        }
        catch (SmtpException ex)
        {
            Log.WriteLog(string.Format("[Send Mail Exception] --> SMTPException has occurred: {0}", ex.Message), LogLevel.Error);
        }
        catch (Exception ex)
        {
            Log.WriteLog(string.Format("[Send Mail Exception] --> Exception has occurred: {0}", ex.Message), LogLevel.Error);
        }
    }

我已经为 NetworkCredential() 尝试了三个可能的用户名登录参数。

提前致谢。

编辑:NTLM 破解

我在代码中添加了以下几行:

FieldInfo transport = _client.GetType().GetField("transport",
    BindingFlags.NonPublic | BindingFlags.Instance);

FieldInfo authModules = transport.GetValue(_client).GetType()
    .GetField("authenticationModules",
        BindingFlags.NonPublic | BindingFlags.Instance);

Array modulesArray = authModules.GetValue(transport.GetValue(_client)) as Array;
modulesArray.SetValue(modulesArray.GetValue(2), 0);
modulesArray.SetValue(modulesArray.GetValue(2), 1);
modulesArray.SetValue(modulesArray.GetValue(2), 3);

我现在收到一条新消息:

Mailbox unavailable. The server response was: relay not permitted

【问题讨论】:

  • 能否请您发布异常的堆栈跟踪?有几个地方可能会出现这种情况。堆栈跟踪将有助于缩小范围。
  • @Ragesh - 刚刚添加到那里。在传递 HTML 时,是否需要对 MailMessage 对象的 body 属性进行编码?
  • 我很确定您不必手动对正文进行编码。我也在使用 HTML 正文,它会自动对其进行编码。
  • 如果您的服务器不喜欢您的 From 或 To 地址(它认为您是垃圾邮件发送者),通常会发生不允许中继。或者,可能是您的用户帐户未正确验证。在这种情况下,我发现使用 Wireshark 查看网络流量是最快的解决方案。使用 Outlook 发送邮件,然后使用您的代码,并确定您的 SMTP 请求和 Outlook 正在执行的操作之间的不同之处。

标签: c# asp.net email smtp smtp-auth


【解决方案1】:

你的第二个问题:

邮箱不可用。服务器响应是:不允许中继

发生这种情况是因为服务器现在没有可接受的身份验证方法,并且不愿意冒险获得“开放中继”的声誉。

这可能是可以修复的。问题是您使用的hack 太重了。它正在覆盖除“Digest”之外的所有身份验证模块,而我们需要做的就是覆盖 NTLM。

试试这个精​​简版:

FieldInfo transport = _client.GetType().GetField("transport",
BindingFlags.NonPublic | BindingFlags.Instance);

FieldInfo authModules = transport.GetValue(_client).GetType()
    .GetField("authenticationModules",
        BindingFlags.NonPublic | BindingFlags.Instance);

Array modulesArray = authModules.GetValue(transport.GetValue(_client)) as Array;
modulesArray.SetValue(modulesArray.GetValue(2), 1);

【讨论】:

  • 这真是太好了。我将考虑在未来的发布周期中实施您的精简版本。
【解决方案2】:

根据以下文章:"Hacking" System.Net.Mail.SmtpClient,当 SmtpClient 选择使用NTLM 身份验证进行身份验证时,可能会引发异常。

这篇文章提供了一个修复,尽管正如文章名称所暗示的那样,它是一个 hack。

然而,在 cmets 中,张贴者还指出,不正确的密码可能会导致同样的异常。

【讨论】:

    猜你喜欢
    • 2017-09-26
    • 2016-11-17
    • 1970-01-01
    • 1970-01-01
    • 2011-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-22
    相关资源
    最近更新 更多