OAuth with Gmail

OAuth is an open protocol to allow secure API authorization in a simple and standard method from desktop and web applications.

In this post I’ll show how to access Gmail account using 3-legged OAuth authentication method with Mail.dll .NET IMAP component. The key advantage of this method is that it allows an application to access user email without knowing user’s password.

You can read more on OAuth authentication with Google accounts here:
http://code.google.com/apis/accounts/docs/OAuth_ref.html

Gmail IMAP and SMTP using OAuth:
http://code.google.com/apis/gmail/oauth/protocol.html

If your application/website is not registered, you should use following key and secret:
consumer key: “anonymous”
consumer secret: “anonymous”

Remember to add reference to Mail.dll and appropriate namespaces.

// C#

using Limilabs.Client.IMAP;
using Limilabs.Client.Authentication;
using Limilabs.Client.Authentication.Google;

const string consumerKey = "anonymous";
const string consumerSecret = "anonymous";

GmailOAuth oauth = new GmailOAuth(consumerKey, consumerSecret);

string url = oauth.GetAuthorizationUrl("http://localhost:64119/");

// ASP.NET client:
// Save oauth in permanent storage:
// Cache[oauth.RequestToken.Token] = oauth;

// Windows client:
Process.Start(url);

// ASP.NET client:
// Response.Redirect(url);

// Windows client with url:
string rawReturnUrl = Console.ReadLine();
ReturnUrl returnUrl = new ReturnUrl(rawReturnUrl);
oauth.GetAccessToken(returnUrl.OAuthVerifier);

// Windows client with verification code (oob):
// string oauthVerifier = HttpUtility.UrlDecode(Console.ReadLine());
// oauth.GetAccessToken(oauthVerifier);

// ASP.NET client: 
// ReturnUrl returnUrl = new ReturnUrl(Request.RawUrl);
// Retrieve oauth from permanent storage:
// GmailOAuth oauth = Cache[returnUrl.OAuthToken]
// oauth.GetAccessToken(returnUrl.OAuthVerifier);

using (Imap client = new Imap())
{
    client.ConnectSSL("imap.gmail.com");
    string oauthImapKey = oauth.GetXOAuthKeyForImap();
    client.LoginOAUTH(oauthImapKey);

    // Now you can access user's emails
    //...

    client.Close();
    oauth.RevokeToken(oauthImapKey);
}

1.
GmailOAuth.GetAuthorizationUrl method returns url you should redirect your user to, so he can authorize access.
As you can see, Mail.dll is asking for access to user’s email information and Gmail access:

2.
If you don’t specify callback parameter, user will have to manually copy&paste the token to your application (oob):

In case of a web project, you can specify a web address on your website. oauth_verifier will be included as the redirection url parameter.

After the redirection, your website/application needs to read oauth_verifier query parameter:

3.
GmailOAuth.GetAccessToken method authorizes the token.

4.
GmailOAuth.GetXOAuthKeyForImap method uses Google API to get the email address of the user, and generates XOAuth key for IMAP protocol (you can use GetXOAuthKeyForSmtp for SMTP).

5.
GmailOAuth.RevokeToken method revokes XOAuth key, so no further access can be made with it.

…and finally VB.NET version of the code:

' VB.NET

Imports Limilabs.Client.IMAP
Imports Limilabs.Client.Authentication
Imports Limilabs.Client.Authentication.Google

Const  consumerKey As String = "anonymous"
Const  consumerSecret As String = "anonymous"

Dim oauth As New GmailOAuth(consumerKey, consumerSecret)

Dim url As String = oauth.GetAuthorizationUrl("http://localhost:64119/")

' ASP.NET client: 
' Save oauth in permanent storage:
' Cache[oauth.RequestToken.Token] = oauth;

' Windows client:
Process.Start(url)

' ASP.NET client: 
' Response.Redirect(url)

' Windows client with url:
Dim rawReturnUrl As String = Console.ReadLine()
Dim returnUrl As New ReturnUrl(rawReturnUrl)
oauth.GetAccessToken(returnUrl.OAuthVerifier)

' Windows client with verification code (oob):
' Dim oauthVerifier As String = HttpUtility.UrlDecode(Console.ReadLine())
' oauth.GetAccessToken(oauthVerifier)

' ASP.NET client: 
' Dim returnUrl As New ReturnUrl(Request.RawUrl)
' Retrive oauth from permanent storage:
' Dim oauth As GmailOAuth = Cache(returnUrl.OAuthToken)
' oauth.GetAccessToken(returnUrl.OAuthVerifier)

Using client As New Imap()
	client.ConnectSSL("imap.gmail.com")
	Dim oauthImapKey As String = oauth.GetXOAuthKeyForImap()
	client.LoginOAUTH(oauthImapKey)

	' Now you can access user's emails
	'...

	client.Close()
	oauth.RevokeToken(oauthImapKey)
End Using

Tags: , , , , , ,

5 Responses to “OAuth with Gmail”

  1. OAuth with IMAP Says:

    […] This article describes generic OAuth class, if you are using Gmail please read OAuth authentication with Gmail […]

  2. Hernan Says:

    Great job! what about oauth v2?

    I have a problem oauth.GetAuthorizationUrl(). When the browser is openned, i get an error from google. If I delete oauth_signature parameter and value from URL it appears to work! but then oauth.GetXOAuthKeyForImap() gives me a 401 error (not authorize)

  3. Limilabs support Says:

    @Hernan

    1.
    Gmail uses OAuth 1.0
    From September 17, 2012 Gmail supports OAuth 2.0 for IMAP and SMTP protocols, Mail.dll also supports IMAP with OAuth 2.0 for ASP.NET (MVC) web applications and IMAP with OAuth 2.0 for installed applications

    2.
    Please update to the latest version.
    – GetAuthorizationUrl now uses not signed OAuthAuthorizeToken method.
    – You’ll no longer get 401 from google API

  4. Mukesh Tyagi Says:

    i am creating a CRM web application. i want that user resister with my app. first time get authenticate with Gmail log in by user name and password and allow access to his user data for my app. but next time when hi log in to my app user can able to see gmail data without log in to gmail. how it posible.

  5. Limilabs support Says:

    Please use OAuth 2.0: http://www.limilabs.com/blog/oauth2-gmail-imap-web-applications – read “Refreshing access token” section.

    Save refresh token to be able to refresh access token. We recommend storing entire IAuthorizationState object received from ProcessUserAuthorization method call. Then use RefreshAuthorization method.

Questions?

Consider using our Q&A forum for asking any questions.