Monday, December 7, 2015

Authenticating apps with Google using OAuth 2.0

OAuth 2.0 is an open standard protocol for authentication and authorization, which is used by Google to provide users and applications with access to its APIs. If you own a Google account you have probably noticed that you can grant and revoke access to your account for desktop and mobile applications. To grant access, you have to log in to your account from within the application and confirm that it can access some (or all) of your data. To revoke access, you can go to your account's settings, select "Connected apps and sites" and remove the application from the list.

But sometimes things become complicated. Calendar-Indicator is an application for Ubuntu written in Python, which integrates nicely with Unity and allows you to access Google calendar directly from your desktop. It also provides you with very nice OSD notifications, so you don't need any extra software (like Evolution or Thunderird) to remind you about incoming events. Unfortunately, being a fantastic application, it has some issues when it comes to authenticating with corporate Google accounts using additional authentication mechanisms, like Active Directory. It's because such mechanisms can use some extra redirections and pop-up windows, which are not handled well by the application's built-in HTML login widget.

To work around this problem, you can authenticate Calendar-Indicator using Google OAuth2 API directly. In order to do this, you need to know the Client Id and Client Secret, which can be considered as application's username and password. When you look into the source code you will find them in share/calendar-indicator/googlecalendarapi.py file:
CLIENT_ID='906536899599-93lne5t3cb0keptl8fh0o8ghpmt447ls.apps.googleusercontent.com'
CLIENT_SECRET='x_QgZkRfUJ_08lWvCw4EIK3U'
They are written in plain text, but it doesn't matter. OAuth protocol is designed in such a way, that learning application's credentials only cannot be used to compromise it.
Having obtained the credentials, you need to use them to ask Google for a permission to access your calendar. To do this, open a web browser and paste the following url into the address bar (the whole text below is one line):
https://accounts.google.com/o/oauth2/auth?response_type=code&access_type=offline
&client_id=906536899599-93lne5t3cb0keptl8fh0o8ghpmt447ls.apps.googleusercontent.com
&redirect_uri=urn:ietf:wg:oauth:2.0:oob&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcalendar
You will be asked to log in to your account and then to grant permission to your calendar. When you agree, you will receive a one-time code, which you need to use to confirm that the application received the permission. The code is placed inside a small input field and is usually a little bit longer than it's size, so make sure you don't miss any characters when copying it into the clipboard.
Now open a terminal window and enter the following command, replacing the string CODE_RECEIVED_FROM_GOOGLE with the actual code (again, the whole text below is one line):
curl -X POST -d "code=CODE_RECEIVED_FROM_GOOGLE
&client_id=906536899599-93lne5t3cb0keptl8fh0o8ghpmt447ls.apps.googleusercontent.com
&client_secret=x_QgZkRfUJ_08lWvCw4EIK3U&redirect_uri=urn:ietf:wg:oauth:2.0:oob
&grant_type=authorization_code" https://accounts.google.com/o/oauth2/token > ~/.config/calendar-indicator/token
When you open ~/.config/calendar-indicator/token file you will notice that it's a JSON object. There are two fields that are important from the application's point of view: access_token and refresh_token. The access_token, combined with Client Id and Client Secret, identifies the application and is valid only for one session only. The refresh_token, also combined with Client Id and Client Secret is used to receive new access_token every time application is run. This way, even when an attacker breaks current access_token, he or she will not be able to create a new application session and compromise the application as a whole.

As you can see, with just two simple steps your application is now securely authorized. When you revoke access to the application or delete the token configuration, you can use aforementioned procedure again to regain access to your calendar.