How to implement OAUTH 2.0 in gmail using Ultimate Mail

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.

1 - Getting Started

  • Register your application at Google for OAuth 2.0 Authentication to access the Client ID and Client Secret for your application.
  • Then enable the access to your Gmail mailbox using IMAP protocol.
  • Add references to Google.API.Oauth2.v2 library using Nuget Package you can use the following command using Nuget Console windows.

    PM>Install-Package Google.Apis.OAuth2.v2

2- How to get OAuth 2.0 access token from Google

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

3- How to get email address which is associated with access token?

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

4- Construct initial XOAUTH2 client response

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

How to establish Session for IMAP or SMTP

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.

45-Day Money Back Guarantee

We will refund your full money in 45 days
if you are not satisfied with our products

Buy Now

Dont miss out Get update on new articles and other opportunities