为了更好地保护您的用户,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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
它适用于新的Google安全策略.
我知道那System.Net.Mail不支持OAuth2.我决定用它MailKit's SmtpClient来发送消息.
经过调查,我了解到我的初始代码没有太大变化,因为MailKit'sAPI看起来非常相似(有System.Net.Mail).
除了一个细节:我需要拥有用户的OAuth访问令牌(MailKit没有可以获取OAuth令牌的代码,但是如果我拥有它,它可以使用它).
所以将来我会有以下几行:
smtpClient.Authenticate (usersLoginName, usersOAuthToken);
Run Code Online (Sandbox Code Playgroud)
我有一个想法添加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
}
Run Code Online (Sandbox Code Playgroud)
怎么弄usersOAuthToken?这是最好的练习技巧Google.Apis.Auth.OAuth2吗?
我上面发布的代码仅适用于GMail,不适用于yandex.ru或其他邮件提供商.为了与他人合作,我可能需要使用另一个OAuth2库.但我不想在我的代码中为许多可能的邮件提供者提供许多身份验证机制.我想为每个邮件提供商提供一个通用解决方案.还有一个可以发送电子邮件的库(比如.net smtpclient)
Ana*_*oly 31
1)使用浏览器登录您的Google帐户,然后转到登录和安全设置.查找两步验证设置.
2)如果两步验证关闭,你想保持这种方式,那就意味着你需要实现许多auth机制,如你所说.
解决方案:打开它,然后生成并使用谷歌应用程序密码.它应该工作!您不需要使用其他库mailkit.
jst*_*ast 17
如何获得usersOAuthToken?
您需要做的第一件事是按照Google的说明获取应用程序的OAuth 2.0凭据.
完成此操作后,获取访问令牌的最简单方法是使用Google的Google.Apis.Auth库:
using System;
using System.Threading;
using System.Security.Cryptography.X509Certificates;
using Google.Apis.Auth.OAuth2;
using MimeKit;
using MailKit.Net.Smtp;
using MailKit.Security;
namespace Example {
class Program
{
public static async void Main (string[] args)
{
var certificate = new X509Certificate2 (@"C:\path\to\certificate.p12", "password", X509KeyStorageFlags.Exportable);
var credential = new ServiceAccountCredential (new ServiceAccountCredential
.Initializer ("your-developer-id@developer.gserviceaccount.com") {
// Note: other scopes can be found here: https://developers.google.com/gmail/api/auth/scopes
Scopes = new[] { "https://mail.google.com/" },
User = "username@gmail.com"
}.FromCertificate (certificate));
// Note: result will be true if the access token was received successfully
bool result = await credential.RequestAccessTokenAsync (CancellationToken.None);
if (!result) {
Console.WriteLine ("Error fetching access token!");
return;
}
var message = new MimeMessage ();
message.From.Add (new MailboxAddress ("Your Name", "username@gmail.com"));
message.To.Add (new MailboxAddress ("Recipient's Name", "recipient@yahoo.com"));
message.Subject = "This is a test message";
var builder = new BodyBuilder ();
builder.TextBody = "This is the body of the message.";
builder.Attachments.Add (@"C:\path\to\attachment");
message.Body = builder.ToMessageBody ();
using (var client = new SmtpClient ()) {
client.Connect ("smtp.gmail.com", 587, SecureSocketOptions.StartTls);
// use the access token as the password string
client.Authenticate ("username@gmail.com", credential.Token.AccessToken);
client.Send (message);
client.Disconnect (true);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是使用Google.Apis.Auth.OAuth2的最佳做法吗?
为什么不使用他们的API来获取身份验证令牌?这似乎是最好的方式让我...
我是否可以向其他非Gmail帐户发送电子邮件?
是的,您通过GMail发送的任何电子邮件都可以发送到任何其他电子邮件地址 - 它不必仅限于其他GMail地址.
| 归档时间: |
|
| 查看次数: |
23736 次 |
| 最近记录: |