30
votes

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", "[email protected]"));
message.To.Add(new MailboxAddress("Mrs. Chanandler Bong", "[email protected]"));
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("[email protected]", "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?

2
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 - Panagiotis Kanavos
I believe this is because you need to setup the connection wiht Oauth 2.0 github.com/jstedfast/MailKit/blob/… - LUIS PEREIRA
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 - Panagiotis Kanavos

2 Answers

30
votes

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 ("[email protected]") {
    // Note: other scopes can be found here: https://developers.google.com/gmail/api/auth/scopes
    Scopes = new[] { "https://mail.google.com/" },
    User = "[email protected]"
}.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 ("[email protected]", 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

27
votes

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", "[email protected]"));
        message.To.Add(new MailboxAddress("Mrs. Chanandler Bong", "[email protected]"));
        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);
        }