为了更好地保护您的用户,GMail和其他邮件Provider 建议将我们的所有应用程序升级到OAuth 2.0.
这意味着System.Net.Mail
不能再工作了,我们需要使用另一个像MailKit
这样的库,我说的对吗?
总的来说,我试图理解如何在不允许"访问不太安全的应用程序"的情况下发送邮箱?
因为我被处决时有System.Net.Mail.SmtpException: The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.5.1 Authentication Required.
人.
如果解决这个问题的唯一方法是使用MailKit
,我认为这个问题将是一个很好的实用的逐步切换教程,从System.Net.Mail
切换到使用MailKit
和Google.Apis.Auth.OAuth2
.我不知道通用解决方案是否会使用DotNetOpenAuth
?
我的应用程序中有以下类,它们对应于向任何地址(gmail、yandex和其他地址)发送邮箱:
public class EmailSender
{
public void SendEmail(SmtpServerSettings serverSettings, SendEmailRequest emailRequest)
{
// Usually I have 587 port, SmtpServerName = smtp.gmail.com
_logger.Trace("Sending message with subject '{0}' using SMTP server {1}:{2}",
emailRequest.Subject,
serverSettings.SmtpServerName,
serverSettings.SmtpPort);
try
{
using (var smtpClient = new SmtpClient(serverSettings.SmtpServerName, (int)serverSettings.SmtpPort))
{
smtpClient.EnableSsl = serverSettings.SmtpUseSsl; // true
if (!string.IsNullOrEmpty(serverSettings.UserName) || !string.IsNullOrEmpty(serverSettings.EncryptedPassword))
{
smtpClient.Credentials = new NetworkCredential(serverSettings.UserName, serverSettings.EncryptedPassword);
}
smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;
smtpClient.Timeout = (int)serverSettings.SmtpTimeout.TotalMilliseconds;
using (var message = new MailMessage())
{
message.From = new MailAddress(serverSettings.FromAddress);
emailRequest.To.ForEach(message.To.Add);
emailRequest.CC.ForEach(message.CC.Add);
emailRequest.Bcc.ForEach(message.Bcc.Add);
message.Subject = emailRequest.Subject.Replace('\r', ' ').Replace('\n', ' ');
message.Body = emailRequest.Body;
message.BodyEncoding = Encoding.UTF8;
message.IsBodyHtml = false;
smtpClient.Send(message);
}
}
_logger.Trace("Sent message with subject '{0}' using SMTP server {1}:{2}",
emailRequest.Subject,
serverSettings.SmtpServerName,
serverSettings.SmtpPort);
}
catch (SmtpFailedRecipientsException e)
{
var failedRecipients = e.InnerExceptions.Select(x => x.FailedRecipient);
LogAndReThrowWithValidMessage(e, EmailsLocalization.EmailDeliveryFailed, failedRecipients);
}
}
}
它在new Google security policies号之前工作得很好.
我知道System.Net.Mail
不支持OAuth2
.我决定用MailKit's
SmtpClient
来发送信息.
经过调查,我知道我的初始代码没有太大变化,因为MailKit's
API看起来非常相似(System.Net.Mail
).
除了一个细节:我需要用户的OAuth访问令牌(MailKit没有获取OAuth令牌的代码,但如果我有,它可以使用它).
因此,在future 我将有以下几行:
smtpClient.Authenticate (usersLoginName, usersOAuthToken);
我想在SendEmail
方法中添加GoogleCredentials
作为新参数:
public void SendEmail(SmtpServerSettings serverSettings, SendEmailRequest emailRequest,
GoogleCredentials credentials)
{
var certificate = new X509Certificate2(credentials.CertificateFilePath,
credentials.PrivateKey,
X509KeyStorageFlags.Exportable);
var credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(credentials.ServiceAccountEmail)
{
Scopes = new[] { "https://mail.google.com/" },
User = serverSettings.UserName
}.FromCertificate(certificate));
....
//my previous code but with MailKit API
}
如何获得usersOAuthToken
分?
我上面发布的代码只适用于GMail,不适用于yandex.ru或其他邮件Provider .为了与他人合作,我可能需要使用另一个OAuth2库.但我不想在我的代码中为许多可能的邮件Provider 提供许多身份验证机制.我想 for each 邮件Provider 提供一个通用解决方案.还有一个可以发送邮箱的库(比如.net smtpclient)