33

According to the new google politics https://googleonlinesecurity.blogspot.de/2014/04/new-security-measures-will-affect-older.html I can't sent an email. "Less secure apps" are considered for google the application which don't use OAuth 2.0.

I would like to use MailKit to solve this problem

var message = new MimeMessage();

message.From.Add(new MailboxAddress("Joey Tribbiani", "noreply@localhost.com"));
message.To.Add(new MailboxAddress("Mrs. Chanandler Bong", "mymail@gmail.com"));
message.Subject = "How you doin'?";
message.Body = new TextPart("plain"){ Text = @"Hey" };

using (var client = new SmtpClient())
{
   client.Connect("smtp.gmail.com", 587);

   ////Note: only needed if the SMTP server requires authentication
   client.Authenticate("mymail@gmail.com", "mypassword");

   client.Send(message);
   client.Disconnect(true);
}

But I have got An exception of type 'MailKit.Security.AuthenticationException' occurred in MailKit.dll but was not handled in user code.Additional information: Authentication failed.

I don't want to change my security settings. Because I want that everything will be secure. That's why I start to use MailKit rather than System.Net.Mail

How can I fix it?

Anatoly
  • 1,908
  • 4
  • 25
  • 47
  • 1
    This isn't about mailkit or C#, it's about Google. Either you have the wrong password or you need to change the security settings of the account [as shown here](http://stackoverflow.com/questions/31231033/using-smtpclient-to-send-an-email-from-gmail) – Panagiotis Kanavos Nov 03 '15 at 10:15
  • 1
    I believe this is because you need to setup the connection wiht Oauth 2.0 https://github.com/jstedfast/MailKit/blob/df7b0f5b9522ed355aa49cfbe56892031d65047f/FAQ.md#how-can-i-log-in-to-a-gmail-account-using-oauth-20 – LUIS PEREIRA Nov 03 '15 at 10:17
  • Actually, there are multiple reasons that GMail can return an authentication error even if the password appears correct - one time passwords, two-factor authentication [as described here](https://support.google.com/accounts/answer/6009563) – Panagiotis Kanavos Nov 03 '15 at 10:18

2 Answers2

31

The first thing you need to do is follow Google's instructions for obtaining OAuth 2.0 credentials for your application.

Once you've done that, the easiest way to obtain an access token is to use Google's Google.Apis.Auth library:

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));

//You can also use FromPrivateKey(privateKey) where privateKey
// is the value of the field 'private_key' in your serviceName.json file

bool result = await credential.RequestAccessTokenAsync (cancel.Token);

// Note: result will be true if the access token was received successfully

Now that you have an access token (credential.Token.AccessToken), you can use it with MailKit as if it were the password:

using (var client = new SmtpClient ()) {
   client.Connect ("smtp.gmail.com", 587);

   // use the OAuth2.0 access token obtained above
   var oauth2 = new SaslMechanismOAuth2 ("mymail@gmail.com", credential.Token.AccessToken);
   client.Authenticate (oauth2);

   client.Send (message);
   client.Disconnect (true);
}

Update:

The above solution is for what Google refers to as "Service Accounts" that are used for server-to-server communication, but if you want OAuth2 support for standard Phone or Desktop apps, for example, you'll need to follow the directions I've written here: https://github.com/jstedfast/MailKit/blob/master/GMailOAuth2.md

jstedfast
  • 35,744
  • 5
  • 97
  • 110
  • Will I can sent mail to "no gmail" account? – Anatoly Nov 03 '15 at 15:26
  • You can't use Google's OAuth2 tokens with non-GMail servers. Is that what you are asking? – jstedfast Nov 03 '15 at 16:08
  • What should I do to sent an email for example to `no_gmail@yandex.ru`? – Anatoly Nov 03 '15 at 16:46
  • Use a regular user name and password. – jstedfast Nov 03 '15 at 16:57
  • If I use System.Net.Mail but with X509Certificate2 will I have problem with a new google secure politics? – Anatoly Nov 03 '15 at 17:01
  • Yes. System.Net.Mail does not support the OAuth2 authentication mechanism. – jstedfast Nov 03 '15 at 22:00
  • Where I can find `cancel` variable? And what to do if result equals false? –  Jan 18 '16 at 10:28
  • it's a `System.Threading.CancellationTokenSource`: https://msdn.microsoft.com/en-us/library/system.threading.cancellationtokensource%28v=vs.110%29.aspx - just create one, or pass `CancellationToken.None` instead of `cancel.Token`. – jstedfast Jan 18 '16 at 15:32
  • I went through a lot trying to get this to work, and it turned out because I have a separate domain myemail@mywebsite.com that is managed by gmail I had to go through specials steps listed here: https://developers.google.com/api-client-library/php/auth/service-accounts#delegatingauthority – JoeBass Mar 11 '17 at 23:18
  • I got the following execption on RequestAccessTokenAsync method.TokenResponseException: Error:"unauthorized_client", Description:"Client is unauthorized to retrieve access tokens using this method.", – Sivanantham Padikkasu May 03 '17 at 19:32
  • SmtpClient obsolete in NET 4.7 ? https://jeffreystedfast.blogspot.com.es/2017/04/achievement-unlocked-mimekit-and.html#gpluscomments – Kiquenet Jul 25 '17 at 20:46
  • @Kiquenet : this SmtpClient is in the Mailkit.Net.Smtp namespace. It is not the same as System.Net.Mail's SmtpClient. – iSpain17 Apr 01 '19 at 18:50
  • what is ***Messagge** ? save in drafts ? – Kiquenet Apr 01 '19 at 19:11
  • hi @jstedfast I use MailKit, but even everything setup correct, I still have Authentication failed. could you please help here: https://stackoverflow.com/questions/60708820/mailkit-authentication-failed – Franva Mar 16 '20 at 15:32
  • I know this is a very old post but it's the one that got me closest to make this thing work. I'm also getting the message "Client is unauthorized to retrieve access tokens using this method". I think I might have to give access to the "https://mail.google.com/" scope to the user in the line' User = "username@gmail.com"', but I haven't found a way to do it yet. Does anyone have an idea on how to do it? – Andre Mar 06 '22 at 00:01
28

Tested following code and works for me:

        // STEP 1: Navigate to this page https://www.google.com/settings/security/lesssecureapps & set to "Turn On"

        var message = new MimeMessage();
        message.From.Add(new MailboxAddress("Joey Tribbiani", "YOU_FROM_ADDRESS@gmail.com"));
        message.To.Add(new MailboxAddress("Mrs. Chanandler Bong", "YOU_TO_ADDRESS@gmail.com"));
        message.Subject = "How you doin'?";

        message.Body = new TextPart("plain")
        {
            Text = @"Hey Chandler,I just wanted to let you know that Monica and I were going to go play some paintball, you in?-- Joey"
        };

        using (var client = new SmtpClient())
        {
            client.Connect("smtp.gmail.com", 587);


            // Note: since we don't have an OAuth2 token, disable
            // the XOAUTH2 authentication mechanism.
            client.AuthenticationMechanisms.Remove("XOAUTH2");

            // Note: only needed if the SMTP server requires authentication
            client.Authenticate("YOUR_GMAIL_NAME", "YOUR_PASSWORD");

            client.Send(message);
            client.Disconnect(true);
        }
Felix
  • 389
  • 3
  • 4
  • 3
    I have tried this and I still get a certificate error, is there anyone else that has had this issue? – Carlos Jimenez Bermudez Apr 23 '17 at 00:17
  • 2
    Works great with me. Perfect for a student project ! Don't you guys forget this to visit this link before trying out this code! : https://www.google.com/settings/security/lesssecureapps – Christopher J. Sep 24 '17 at 22:08
  • So anyone who hacks your program will see your Google mail password? Doesn't seem like a good idea to me! – Tim Makins Apr 25 '19 at 09:32
  • Works on me. I used in it my test application - using my test gmail account. In production, I used my client email's smtp server. so no problem with other programmer (or worst hacker) seeing my "App password" - this is just a gmail test account and I can revoke this App password anytime. – Fadz Feb 01 '20 at 11:08