Pour mieux protéger vos utilisateurs, GMail et d'autres fournisseurs de messagerie recommandent de mettre à niveau toutes nos applications vers OAuth 2.0.
Ai-je raison de dire que cela signifie que System.Net.Mail
ne fonctionnent plus et nous devons utiliser une autre bibliothèque comme MailKit
?
En général, j'essaie de comprendre comment envoyer un courriel sans autoriser "l'accès aux applications moins sécurisées" ?
Parce que j'ai 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.
Lorsque smtpClient.Send(message);
exécuté.
Si la seule façon de résoudre ce problème est d'utiliser MailKit
Je pense que cette question sera un bon tutoriel pratique sur la commutation, étape par étape, à partir de System.Net.Mail
à l'utilisation MailKit
y Google.Apis.Auth.OAuth2
. Je ne sais pas si la solution générale sera d'utiliser DotNetOpenAuth
?
J'ai la classe suivante dans mon application qui correspond à envoyer un email à n'importe quelle adresse (gmail, yandex et autres) :
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);
}
}
}
Cela fonctionne bien jusqu'à ce que le les nouvelles règles de sécurité de Google .
Sé que System.Net.Mail
ne prend pas en charge OAuth2
. J'ai décidé d'utiliser MailKit's
SmtpClient
pour envoyer des messages.
Après l'enquête, je comprends que mon code initial ne change pas tellement, parce que MailKit's
L'API est très similaire (avec System.Net.Mail
).
A un détail près : Je dois disposer du jeton d'accès OAuth de l'utilisateur (MailKit ne dispose pas de code permettant de récupérer le jeton OAuth, mais il peut l'utiliser si je l'ai).
Ainsi, à l'avenir, j'aurai la ligne suivante :
smtpClient.Authenticate (usersLoginName, usersOAuthToken);
J'ai une idée à ajouter GoogleCredentials
comme nouveau paramètre à la SendEmail
méthode :
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
}
Comment obtenir usersOAuthToken
? Est-ce la meilleure technique à utiliser Google.Apis.Auth.OAuth2
?
Le code que j'ai posté ci-dessus est pour GMail SEULEMENT et ne fonctionnera PAS pour yandex.ru ou d'autres fournisseurs de messagerie. Pour travailler avec d'autres, j'aurai probablement besoin d'utiliser une autre bibliothèque OAuth2. Mais je ne veux pas avoir de nombreux mécanismes d'authentification dans mon code pour de nombreux fournisseurs de messagerie possibles. J'aimerais avoir UNE SOLUTION GÉNÉRALE pour tous les fournisseurs de courrier électronique. Et une bibliothèque qui peut envoyer des e-mails (comme .net smtpclient).
S'il vous plaît, aidez-moi !