Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.

Channels ▼

JVM Languages

Getting Started with Google Apps and OAuth

Although a purchased certificate is generally of more utility, you do have to purchase it, and the certificate will have to be formatted in a way that your server software understand. The certificate encoding required by your web server may not be acceptable to Google, however. (But it might be. It can't hurt to try using an existing certificate, if you have one.) Let's look at a slightly different approach.

The service that you're actually purchasing from the Certificate Authority (CA) is the "trusted third party" aspect of what a certificate does. That is, the CA is certifying that you're actually who you say you are, and that you own the domain that you say you own. In the case of Google, you can prove that you are who you claim to be simply by logging in. You'll also, typically, have to prove that you own the domain, which in Google's case involves uploading a magic file to the website or modifying your DNS zone file. Google guides you through this process when you set up your Google Apps account.

Since Google is taking on the authentication part of the CA function, it's a bit more lax about the sorts of certificates it will accept from you. In particular, Google is happy with a a "self-signed" certificate — one that you sign yourself using your own private key. A self-signed cert is utterly worthless for use for supporting HTTPS in Apache, since no browser will trust it, but it's actually fine for OAuth purposes. Google has provided instructions for creating a "self-signed" certificate here, but the basic request is:

openssl req -x509 -nodes -days 365 -newkey rsa:1024 -sha1 \
	-subj '/C=US/ST=CA/L=Berkeley/CN=www.myDomain.com' \
	-keyout myrsakey.pem -out myrsacert.pem

This single command both creates the key (in the file myrsakey.pem) and a cert (in the file myrsacert.pem) that conforms's to the X.509 standard. This particular certificate is valid for 365 days, uses a 1024-bit RSA public-key algorithm, and contains the information about you that's listed in the -subj argument. (This information is the same information you would have specified when creating CSR, as I described earlier.) As before, save the key file in at least two safe places.

Once you've created the certificate file, you need to register it with Google. Google provides instructions here, but if you have Google Apps set up, you can register the domain on your Manage Your Domains page.

The OAuth Dance

That's all the advance prep we have to do, so let's move on to OAuth itself. Figure 1 shows the basic flow through the process. (You can watch this flow by going through the process manually using the OAuth Playground app).

[Click image to view at full size]
Figure 1: OAuth Flow

  1. Starting at the top left of Figure 1, a Web Application (running on the browser) decides that it needs authorization (probably because the OAuth User clicked on a button during the account-creation process). The application sends off an AJAX request-authorization message to the server side (the OAuth Consumer application).
  2. The Consumer asks the Service Provider for a "Request Token." The request specifies exactly what information you want to access. (In Google's case, this specification typically takes the form of a URL. For example, you can request access to all of a User's calendars with https://www.google.com/calendar/feeds/, and other URLS can request access to specific calendars or other services entirely. The request is digitally signed, by the way, using the private key I discussed earlier. The returned token is considered "unauthorized," which is to say, you won't be able to do anything with it until after the user has granted access permission to the Consumer. To grant permission:
  3. The Consumer creates an authorization URL, concatenating information in the returned Request Token with arbitrary arguments of its own and sends that URL back down to the web app, which displays the URL as a link or a button of some sort.
  4. The User clicks the button to get to an authorization page on the Service Provider's website. Figure 2 shows what Google's authorization page looks like. Note that the OAuth request token is right there in the URL).
    [Click image to view at full size]
    Figure 2: Authorization Screen.

    It's important to realize that your User is now interacting with Google, not with your application. If necessary, Google will force the User to log in to get to this page. Because the Consumer is not involved, it has no access to the User's login information. Once the User has authorized access, Google will remember that fact internally and associate the authorization with the Request Token issued in Step 2.
  5. The Service Provider (Google) now sends an HTTP POST to the Consumer to tell it that the User is done. You provided the URL for that POST back in Step 2, and the Request Token is included as the Payload.
  6. The Consumer now coverts the Request Token to an Access Token that can actually be used to grant access to the data. It passes the Request Token back up to the Service Provider, which looks it up to see if authorization was granted back in step 4. If so, the Service Provider returns an Access Token, which the Consumer squirrels away in the Database. That Access Token is good indefinitely — until the User logs on to Google and deauthorizes it.
  7. Thereafter, a user accesses the data by making a request to Google using a service-specific API. Only requests that contain a valid Access Token will be honored.

We'll look at the actual code that implements this process next month.

Security Issues

Before leaving the subject of OAuth entirely, I do want to point out a few security issues.

First, never store the Access Token in a cookie. No matter how tempting it is for your web app to make calls directly to the Service Provider, the calls all should go through the Consumer, which stores the Access Token and adds it to the request. The problem here is a common exploit called Cross-Site Scripting (or Script Injection). Consider Facebook. The content of the page that's displayed when you log in is not provided entirely by you and Facebook. Some of the content (comments on your Wall, for example) come from a third party. (The same reasoning applies to blog comments, etc.) Now, imagine for a moment that that comment contains an HTML <script> element that holds an malicious chunk of JavaScript. That is, our hacker just typed in the JavaScript when he posted the comment, and that JavaScript was stored verbatim in the database and served back out along with the page. (Let's hope that Facebook, or whatever open-source blogging package you might use, isn't that sloppy!) That evil JavaScript executes as soon as your page is loaded. It reads the cookies (which it can do because the browser thinks it came from a trusted source) and then issues an an HTTP GET request to an evil server, with all of your cookie data appended to the URL as a long argument string. The evil server now has your Access Token, and can get at (or modify) your Service-Provided data.

Preventing this attack is relatively easy: You have to examine all input from all users and remove any <script> elements. Unfortunately, the odds of that "scrubbing" being done correctly everywhere in the application are not great in most programming shops, where most programmers know little or nothing about security. Not putting the cookie onto the client provides an extra measure of safety — one that's not necessary if the user input is scrubbed properly, but that provides some insurance in case the data isn't scrubbed.

The second issue is really beyond the scope of this article, but there is a security flaw in OAuth itself, documented in the article: Explaining the OAuth Session Fixation Attack. This attack is a social-engineering attack, but it's still important to know about so that you can put defensive measures in place.

As I mentioned previously, in the next installment, we’ll step through code implementations. If you want to race ahead and explore this yourself in the interim, some useful resources are listed below.

Useful Links

OAuth community site.

Beginner's Guide to OAuth.

Explaining the OAuth Session Fixation Attack.

Google Documentation:

Related Articles

Getting Started With the Cloud: Logging On With Google OAuth

Getting Started with The Cloud: The Ecosystem

Related Reading

More Insights

Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.