跳到主要内容

outlook 发送邮件时报错

· 阅读需 2 分钟

在使用 .net 自带的 SmtpClient 发送邮件的时候报错:

Unhandled exception. System.Net.Mail.SmtpException: The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.7.57 Client not authenticated to send mail. Error: 535 5.7.139 Authentication unsuccessful, the user credentials were incorrect.

如果确认账号密码填写正确,并且 SMTP 服务器地址也填写正确,那有可能是微软账号开启了多重身份验证 (MFA),这时候就需要使用应用密码而不是普通密码来进行 SMTP 身份验证。

去微软账户的管理后台创建一个应用密码:https://account.live.com/proofs/Manage/additional?mkt=zh-cn, 创建完成之后就可以在 .net 中发送邮件了,但是如果是在 go 语言中使用标准库发送邮件,仍然会报类似的错误,原因是 Go 语言标准库的 SMTP 客户端只支持 PLAIN 和 CRAM-MD5 身份认证机制,而微软的 outlook 邮箱的 SMTP 使用的是 LOGIN 身份认证机制,所以需要自行实现 smtp.Auth 接口,下面是 LOGIN 身份认证方法的实现:

// loginAuth is an smtp.Auth that implements the LOGIN authentication mechanism.
type loginAuth struct {
username string
password string
host string
}

func (a *loginAuth) Start(server *smtp.ServerInfo) (string, []byte, error) {
if !server.TLS {
advertised := false
for _, mechanism := range server.Auth {
if mechanism == "LOGIN" {
advertised = true
break
}
}
if !advertised {
return "", nil, errors.New("gomail: unencrypted connection")
}
}
if server.Name != a.host {
return "", nil, errors.New("gomail: wrong host name")
}
return "LOGIN", nil, nil
}

func (a *loginAuth) Next(fromServer []byte, more bool) ([]byte, error) {
if !more {
return nil, nil
}

switch {
case bytes.Equal(fromServer, []byte("Username:")):
return []byte(a.username), nil
case bytes.Equal(fromServer, []byte("Password:")):
return []byte(a.password), nil
default:
return nil, fmt.Errorf("gomail: unexpected server challenge: %s", fromServer)
}
}