对“服务器违反协议”进行故障排除使用 SmtpClient 发送邮件时

发布于 2024-08-24 01:03:42 字数 955 浏览 7 评论 0原文

我想使用 SmtpClient 类发送邮件消息。

这是我使用的代码:

SmtpClient smtpClient = new SmtpClient("Host",25);
NetworkCredential basicCredential =
new NetworkCredential("UserName", "Password");
MailMessage message = new MailMessage();
MailAddress fromAddress = new MailAddress("[email protected]");
smtpClient.UseDefaultCredentials = false;
smtpClient.Credentials = basicCredential;
message.From = fromAddress;
message.Subject = "test send";
message.IsBodyHtml = true;
message.Body = "<h1>hello</h1>";
message.To.Add("[email protected]");
smtpClient.Send(message);

但它总是抛出异常:

服务器违反协议服务器响应为:UGFzc3dvcmQ6

我找不到原因。请,如果有人遇到过类似的事情,请告诉我该怎么办。

I want to send a mail message with the SmtpClient class.

Here's the code I use:

SmtpClient smtpClient = new SmtpClient("Host",25);
NetworkCredential basicCredential =
new NetworkCredential("UserName", "Password");
MailMessage message = new MailMessage();
MailAddress fromAddress = new MailAddress("[email protected]");
smtpClient.UseDefaultCredentials = false;
smtpClient.Credentials = basicCredential;
message.From = fromAddress;
message.Subject = "test send";
message.IsBodyHtml = true;
message.Body = "<h1>hello</h1>";
message.To.Add("[email protected]");
smtpClient.Send(message);

But it always throws an exception:

The server committed a protocol violation The server response was: UGFzc3dvcmQ6

I can't find the reason for that. Please, if anyone has faced something like this, tell me what to do.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

梦幻的心爱 2024-08-31 01:03:42

我遇到了同样的问题,对于我的情况,它是设置 user@domain 而不是 user,我的意思是

旧代码

new NetworkCredential("[email protected]", "Password");

新代码

new NetworkCredential("UserName", "Password");

I had the same problem, for my case it was for setting user@domain instead of user, I mean

Old code

new NetworkCredential("[email protected]", "Password");

New code

new NetworkCredential("UserName", "Password");
知足的幸福 2024-08-31 01:03:42

在我看来,SmtpClient 身份验证在某种程度上失去了步调。

一些身份验证机制是“客户端:使用用户名和密码请求身份验证,服务器:成功/失败”,其他身份验证机制是“客户端:使用用户名请求身份验证,服务器:请求密码,客户端:使用密码回复,服务器:成功/失败”。

看起来 SmtpClient 期待前者,而您的服务器期待后者。

正如戴夫·温塔建议的,会话日志会告诉您 SmtpClient 尝试使用什么身份验证机制,但它也会说明服务器支持什么身份验证机制。

通常发生的情况是,服务器提供许多身份验证选项,而客户端选择要使用的选项。那里的行为应该由所选的协议决定。我希望 SmtpClient 类可以为您解决这个问题,但恐怕我从未使用过该特定类。

另请记住 - 如果您要在此处发布日志,请在记录会话之前更改为一次性密码,因为可以轻松地将 Base64 编码的纯文本密码更改回人类可读的纯文本密码。

This looks to me like SmtpClient authentication is somehow getting out of step.

Some authentication mechanisms are "Client: request auth with username and password, Server: success/fail" others are "Client: request auth with username, Server: request password, Client: reply with password, Server: success/fail".

It looks like SmtpClient is expecting the former, while your server is expecting the latter.

As dave wenta suggested, a log of a session would tell you what auth mechanism SmtpClient is trying to use, but it will also say what auth mechanisms the server supports.

What normally happens is that the server offers a number of authetication options, and the client choses which one it is going to use. The behaviour from there should be determined by the protocol chosen. I would hope that the SmtpClient class took care of that for you though, but I'm afraid I've never used that particular class.

Also remember - If you are going to post a log here, change to a throwaway password before you log the session, as a base64 encoded plain text password can be trivially changed back to human readable plain text password.

儭儭莪哋寶赑 2024-08-31 01:03:42

UGFzc3dvcmQ6 是“密码:”base 64 编码(不带引号),这意味着密码可能是错误的或未编码发送。尝试使用 Base 64 编码密码:

string password = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes("Password));

UGFzc3dvcmQ6 is "Password:" base 64 encoded (without quotes), meaning the password is probably wrong or not send encoded. Try base 64 encoding the password:

string password = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes("Password));
但可醉心 2024-08-31 01:03:42

启用 System.Net.Mail 的日志记录。然后查看日志文件。这将准确地向您显示 SMTP 层发生的情况。

以下是包含更多信息的链接:

http://systemnetmail.com/faq/4.10.aspx

Enable logging for System.Net.Mail. Then view the log file. This will show you exactly what is happening during the SMTP layer.

Here is a link with more info:

http://systemnetmail.com/faq/4.10.aspx

后来的我们 2024-08-31 01:03:42

Google 上 UGFzc3dvcmQ6 的点击量

似乎是服务器期望加密(使用 base64)用户名/密码

thousand of hit on google for UGFzc3dvcmQ6

it seem the server expect encrypted(with base64) username/password

a√萤火虫的光℡ 2024-08-31 01:03:42

有同样的问题。通过以下步骤解决了它:
1) 通过使用 Telnet 或 putty 或任何其他终端连接到 SMTP 服务器,找出服务器为 SMTP 身份验证提供的内容:

telnet xxx.yyy.zzz.aaa 587 

(xxx.yyy.zzz.aaa = SMTP 服务器的 IP 地址,587 = 端口号)

<服务器回复“220协议+版本+时间”

ehlo testing

<服务器显示功能列表,例如

250-AUTH NTLM CRAM-MD5 LOGIN

SMTP 客户端首先尝试采用最安全的协议。就我而言:

1. System.Net.Mail.SmtpNegotiateAuthenticationModule
2. System.Net.Mail.SmtpNtlmAuthenticationModule
3. System.Net.Mail.SmtpDigestAuthenticationModule
4. System.Net.Mail.SmtpLoginAuthenticationModule

看起来好像 SMTP 客户端尝试 NTLM,而服务器尝试运行 LOGIN。

通过黑客攻击(参见 https: //blogs.msdn.microsoft.com/knom/2008/04/16/hacking-system-net-mail-smtpclient/),除了服务器假定的协议(登录于本例):

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

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

Array modulesArray = authModules.GetValue(transport.GetValue(smtpClient)) as Array;
foreach (var module in modulesArray)
{
    Console.WriteLine(module.ToString());
}
// System.Net.Mail.SmtpNegotiateAuthenticationModule
// System.Net.Mail.SmtpNtlmAuthenticationModule
// System.Net.Mail.SmtpDigestAuthenticationModule
// System.Net.Mail.SmtpLoginAuthenticationModule

// overwrite the protocols that you don't want
modulesArray.SetValue(modulesArray.GetValue(3), 0);
modulesArray.SetValue(modulesArray.GetValue(3), 1);
modulesArray.SetValue(modulesArray.GetValue(3), 2);

Had the same problem. Solved it in the following steps:
1) find out, what the server offers for SMTP Authentication by connecting to the SMTP Server using Telnet or putty or any other terminal:

telnet xxx.yyy.zzz.aaa 587 

(xxx.yyy.zzz.aaa = IP address of the SMTP Server, 587 = port number)

< Server answers with "220 protocol + version + time"

ehlo testing

< Server displays list of capabilities e.g.

250-AUTH NTLM CRAM-MD5 LOGIN

The SMTP client tries to take the most secure protocol first. In my case:

1. System.Net.Mail.SmtpNegotiateAuthenticationModule
2. System.Net.Mail.SmtpNtlmAuthenticationModule
3. System.Net.Mail.SmtpDigestAuthenticationModule
4. System.Net.Mail.SmtpLoginAuthenticationModule

It looks as if the SMTP client tries NTLM while the server tries to run LOGIN.

With a hack (cf. https://blogs.msdn.microsoft.com/knom/2008/04/16/hacking-system-net-mail-smtpclient/), all protocols can be turned of except for the one the server assumes (LOGIN in this case):

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

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

Array modulesArray = authModules.GetValue(transport.GetValue(smtpClient)) as Array;
foreach (var module in modulesArray)
{
    Console.WriteLine(module.ToString());
}
// System.Net.Mail.SmtpNegotiateAuthenticationModule
// System.Net.Mail.SmtpNtlmAuthenticationModule
// System.Net.Mail.SmtpDigestAuthenticationModule
// System.Net.Mail.SmtpLoginAuthenticationModule

// overwrite the protocols that you don't want
modulesArray.SetValue(modulesArray.GetValue(3), 0);
modulesArray.SetValue(modulesArray.GetValue(3), 1);
modulesArray.SetValue(modulesArray.GetValue(3), 2);
一人独醉 2024-08-31 01:03:42

当您不提供密码时也可能会发生这种情况。就我而言,我使用的是 web.config smtp 块中的凭据,并且在我的部署服务器上(使用 octopus 部署)忘记填充密码属性。

This can also happen when you simply don't provide the password. In my case I was using credentials from a web.config smtp block and on my deployment server (using octopus deploy) had forgotten to populate the password attribute.

清眉祭 2024-08-31 01:03:42

对于在谷歌上遇到此问题的其他人..我通过以“用户名”格式而不是“域\用户名”提供我的用户名来修复此问题

$Credential = Get-Credential

Send-MailMessage -SmtpServer exchange.contoso.com -Credential $Credential -From '[email protected]' -To '[email protected]' -Subject 'Test email' -Port 587 -UseSsl

For anyone else coming across this on google.. I fixed this by supplying my username in the "username" format instead of "DOMAIN\username"

$Credential = Get-Credential

Send-MailMessage -SmtpServer exchange.contoso.com -Credential $Credential -From '[email protected]' -To '[email protected]' -Subject 'Test email' -Port 587 -UseSsl
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文