为了更好地保护您的用户,GMail和其他邮件提供商建议将我们所有的应用程序升级到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.当smtpClient.Send(message);执行。
如果要解决这个问题的唯一方法是使用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);
}
}
}
在使用新的Google安全策略之前,它可以正常工作。
我知道System.Net.Mail不支持OAuth2。我决定用来MailKit's SmtpClient发送消息。
经过调查后,我知道我的初始代码变化不大,因为MailKit'sAPI看起来非常相似(与System.Net.Mail)。
除了一个细节:我需要拥有用户的OAuth访问令牌(MailKit没有可获取OAuth令牌的代码,但如果有的话,它可以使用它)。
因此,将来我会有以下内容:
smtpClient.Authenticate (usersLoginName, usersOAuthToken);
我有一个想法要添加GoogleCredentials为SendEmail方法的新参数:
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?是使用的最佳实践技术Google.Apis.Auth.OAuth2吗?
我上面发布的代码仅适用于GMail,不适用于yandex.ru或其他邮件提供商。要与他人合作,我可能需要使用其他OAuth2库。但是我不想在我的代码中为许多可能的邮件提供者提供许多身份验证机制。我想为每个邮件提供商提供一个通用的解决方案。还有一个可以发送电子邮件的库(就像.net smtpclient一样)