新しいセキュリティポリシーに従って、.Netで電子メールを送信するにはどうすればよいですか?
質問
ユーザーをより良く保護するために、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's
API は非常によく似ています(
System.Net.Mail
).
ただし、1つだけ細かい点があります。ユーザーの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ライブラリを使用する必要があります。しかし、私は多くの可能なメールプロバイダに対応するために、多くの認証メカニズムを私のコードに持ちたくはありません。私は、すべてのメールプロバイダに対応する1つの一般的なソリューションを持っていたいのです。そして、メールを送信することができる1つのライブラリ(.net smtpclientがそうであったように)。
どのように解決するのですか?
1) ブラウザーを使ってGoogleアカウントにログインし、サインインとセキュリティの設定に進みます。2段階認証の設定を探します。
2) 2段階認証がオフで、その状態を維持したい場合、あなたが言ったように、多くの認証メカニズムを実装する必要があることを意味します。
解決策 それをオンにして、Google アプリのパスワードを生成して使用します。これでうまくいくはずです。のような他のライブラリを使用する必要はありません。
mailkit
.
関連
-
[解決済み】「入力文字列が正しい形式ではありませんでした」エラーの解決方法は?[重複しています]。
-
[解決済み】HRESULTからの例外:0x800A03ECエラー
-
VSでscanfエラーを恒久的に解決するには、ソースファイルを作成し、自動的に#define _CRT_SECURE_NO_WARNINGS 1を追加してください。
-
[解決済み] .NETでC#オブジェクトをJSON文字列に変換するには?
-
[解決済み] .NETでフォーマット文字列のブレース(中括弧)をエスケープする方法
-
[解決済み] .NETコンソールアプリケーションでアプリケーションのパスを取得するにはどうすればよいですか?
-
[解決済み] .NETアプリケーションを強制的に管理者として実行させるにはどうしたらいいですか?
-
[解決済み] .NETでGmailを使ったメール送信
-
[解決済み】Gmailエラー :SMTPサーバーが安全な接続を要求しているか、クライアントが認証されていません。というサーバーの応答がありました。5.5.1 認証が必要です
-
[解決済み】C#でGmailのSMTPサーバーを経由してメールを送信する場合
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】C#で四捨五入する方法
-
[解決済み】C#におけるtypedefの等価性
-
[解決済み] 保護レベルによりアクセス不能になりました。
-
[解決済み] エンティティタイプ <type> は、現在のコンテキストのモデルの一部ではありません。
-
[解決済み】トランスポート接続からデータを読み取れない:既存の接続は、リモートホストによって強制的に閉じられました。
-
[解決済み】ランダムなブーリアンを生成する最速の方法
-
[解決済み] 関数を終了するには?
-
[解決済み】別のスレッドがこのオブジェクトを所有しているため、呼び出し側のスレッドはこのオブジェクトにアクセスできない
-
[解決済み] .NETでGmailを使ったメール送信
-
[解決済み】Gmailエラー :SMTPサーバーが安全な接続を要求しているか、クライアントが認証されていません。というサーバーの応答がありました。5.5.1 認証が必要です