Google Account passwords are precious, and it's not a realistic plan to share them with random third-party applications you don't trust. That's why Google has been promoting OAuth a pair of .0. AN open authentication protocol that produces it attainable for users to grant access to Gmail and different services to third-party applications while not having to reveal their countersign to them.
For the same reason, username/password authentication is disabled by default once accessing Gmail mailbox victimization IMAP, POP3 or SMTP protocols. Following errors occur once authenticating with classic IMAP/POP3/SMTP purchasers. You can log in via a web browser to see this click on the link below: Here and AUTH
Although you can still allow credentials access if you enable LESS SECURE APPS in your Google account settings, but using OAuth 2.0 is a better choice. Here I will guide you the whole process how you can use OAuth 2.0 with UltimateMail.
PM>Install-Package Google.Apis.OAuth2.v2
First, your application needs to access the OAuth 2.0 token by using google.APIs.OAuth2.v2 package and its GoogleWebAuthorizationBroker.AuthorizeAsync() method. This would make the user possible to authenticate to Google account without revealing his password to the application.
Below is the source code which shows the process:
C#
// used namespaces using System.IO;
using System.Threading;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Util.Store;
// client ID and client secret, which identifies your application
const string ClientId = @"CLIENT-ID";
const string ClientSecret = @"CLIENT-SECRET-HERE";
// path to local token storage
const string TokenStoragePath = @"c:\data\user-tokens";
// scope definition for accessing Gmail and getting email info
static readonly string[] GmailScope = { "https://mail.google.com", "email" };
/// Local ID can be any string e.g. username.</param>
/// <returns>The Google's OAuth 2.0 access token.</returns>
static string GetAccessToken(string localId)
{
// prepare client secrets
var secrets = new ClientSecrets();
secrets.ClientId = ClientId;
secrets.ClientSecret = ClientSecret;
// get Google's user credential
UserCredential credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
secrets, // client secrets
GmailScope, // scope to access Gmail
localId, // token ID
CancellationToken.None, // no cancellation
new FileDataStore(TokenStoragePath, true) // file storage for
tokens).Result;
// refresh token if necessary RefreshToken(credential, false);
// return access token
return credential.Token.AccessToken;
}
/// <summary>
/// Refreshes the Google's OAuth 2.0 token.
/// </summary>
/// <param name="credential">User credential holding the token.</param>
/// <param name="force">True to force refreshing; false to refresh only if token is expired.</param>
static void RefreshToken(UserCredential credential, bool force)
{
// check whether to refresh the token
if (force ||credential.Token.IsExpired(Google.Apis.Util.SystemClock.Default))
{
bool succes;
Google.GoogleApiException error = null;
try
{
// refresh token
succes = credential.RefreshTokenAsync(CancellationToken.None).Result;
}
catch (Google.GoogleApiException ex)
{
succes = false;
error = ex;
}
if (!succes)
throw new InvalidOperationException("Refreshing OAuth 2.0 token failed.", error);
}
}
You need your account e-mail along with access token to authenticate to Gmail with IMAP and SMTP using OAuth 2.0 for incoming and outgoing mail, the Google.Apis.OAuth2.v2 package will be used to retrieve the address associated with the token using the method Oauth2Service.Tokeninfo()
C#
// used namespaces
using Google.Apis.Oauth2.v2;
using Google.Apis.Services;
/// <summary>
/// Gets the email address associated with Google's OAuth 2.0 token.
/// </summary>
/// <param name="accessToken">Google's OAuth 2.0 access token.</param>
/// <returns>The email address associated with Google's OAuth 2.0 token.</returns>
static string GetEmail(string accessToken)
{
try
{
// request token info
var service = new Oauth2Service(new BaseClientService.Initializer());
var req = service.Tokeninfo();
req.AccessToken = accessToken;
var tokeninfo = req.Execute();
// return email associated with given token
return tokeninfo.Email;
}
catch (Google.GoogleApiException ex)
{
throw new InvalidOperationException("Extracting email address from OAuth 2.0 token failed.", ex);
}
}
Now, the application has everything it needs. But before it actually establishes an IMAP or SMTP session, it has to construct an initial client response (used instead of username/password credentials) from the access token and e-mail address:
// used namespaces
using System.Text;
/// <summary>
/// Gets the initial client response in SASL XOAUTH2 format.
/// </summary>
/// <param name="email">The email address associated with Google's OAuth 2.0 token.</param>
/// <param name="accessToken">Google's OAuth 2.0 access token.</param>
/// <returns>The initial client response in SASL XOAUTH2 format.</returns>
static string PrepareInitialResponse(string email, string accessToken)
{
// SASL XOAUTH2 initial client response format:
// base64("user=" {email} "^A" "auth=Bearer " {access token} "^A^A")
// prepare XOAUTH2 initial client response
string raw = string.Format("user={0}{1}auth=Bearer {2}{1}{1}", email, '\x1', accessToken);
return Convert.ToBase64String(Encoding.ASCII.GetBytes(raw));
}
Now, the app can use UltimateMail to connect to Gmail using IMAP protocol and authenticate using the XOAUTH2 initial client response constructed from the OAuth 2.0 token:
Below is the sample code of how to use UltimateMail for IMAP using Password:
Although there are other methods to authenticate as well like NTLM, and client certificates but we will check it using Authenticate
with a password
// Create a new instance of the Imap class.
Imap client = new Imap();
// Connect to the server.
client.Connect("myserver");
// Or you can specify the IMAP port with
// client.Connect("myserver", 143);
// Login to the server.
client.Authenticate("user", "password");
StringBuilder sb = new StringBuilder();
var list = client.ListFolders();
for (int i = 0; i < list.Count; i++)
{
sb.AppendFormat("{0} - {1}\r\n", i + 1, list[i].Name);
}
Console.WriteLine(sb.ToString());
// Close the connection.
client.Disconnect();
So now your application would be able to access your Gmail box using UltimateMail and OAuth 2.0. I have attached a code sample for IMAP console client for using OAuth 2.0 using Ultimate Mail, the source folder contains the code for VS 2005 through VS 2019.