This is the start of an article series, provided that I don’t get distracted and forget to continue the series.
I’ve been working on what is going to ultimately be a large-scale web project. The details of the application are under wraps right now, but the first thing I started working on was authentication. I knew I didn’t want to deal with user account registration and securing user credentials. It’s just not worth the security risk – the security fiasco LinkedIn dealt with last year shows that even big companies can be susceptible to security holes. So, with that in mind, we decided to first implement Google authentication.
Google uses an extension of OpenID, called OAuth2, to provide user authentication and access to Google services and APIs. OAuth gives the user and the authentication provider more control over what happens once the user is logged in – Facebook uses the same technology. You see this whenever you grant access to a website or application to use your Facebook or Google account, and the authorization page tells you exactly what the service is going to do with your account (e.g. post to Facebook on your behalf, manage your Gmail contacts, etc.). Google only recently started supporting OAuth2, and as a result, existing third-party web application libraries still use Google’s older OpenID implementation.
Because of the scope of this project, we didn’t want to rely on any third-party libraries for anything – especially not a component as crucial as user authentication. I started investigating how to use Google’s implementation of OAuth2 using ASP.NET C#, completely from scratch. It took a bit of trial and error and a lot of research on both MSDN and Google’s reference information to figure it out. Unfortunately, most developers just use existing libraries like DotNetOpenAuth (which was recently dropped by its biggest contributor, doesn’t support OAuth2 for Google, and has a tenuous future at this point), so I didn’t get much help from others.
This article series is going to cover implementing Google OAuth2 in ASP.NET C# applications, from start to finish. Hit the jump to get started!
Step-by-Step Authentication Process
First off, let’s look at what exactly we need to do with our code to allow logging in to Google and, more importantly, verifying that the login information is valid and that the login session from Google hasn’t been compromised or tampered with.
- Send the user to Google’s login service via URL
- Process the GET data returned by Google
- Request user details from Google via POST
- Verify the returned user data is valid
That was easy!
Okay…so maybe it’s not quite that simple. On the other hand, it’s also not as scary as many developers believe it is. C# has excellent support for the RSA cryptography that Google uses to sign authentication data sent back to your application, which makes it surprisingly easy to handle the third step – verifying the data.
The first step is the easiest, so we’re going to cover that to get started.
Sending the user to Google’s login service
In order for your application to use Google’s OAuth2 service, there’s a few things you need to do first.
Before you do anything, set up a Google account for your application. You can use an existing Google account, but I opted to create an account using an email under my new project’s domain in order to keep this project separate from my personal online identity. Once that’s done, log in to Google’s developer API console. Follow the instructions to create a new application – it’s pretty straightforward. You’re going to need to note down two important pieces of information provided by the API Console: your client ID and your client secret. Your client id is a unique identifier that tells Google what API project is being used. This doesn’t change. It’s also publicly visible in the login URL that your user will see in their browser’s address bar during the login process.
Your client secret, on the other hand, is just that – a secret. This is going to be sent to Google over an SSL-encrypted channel using POST. It’s also all done on the server side, so as long as your server is secure, this piece of information is safe. The client secret is what tells Google that you are who you say you are and that your application has permission to use the API project you created through Google. If your client secret is ever compromised, you can easily generate a new secret through the API console.
The last thing you need to remember is what specific URIs you authorized as redirect URIs. Google’s API will not allow authentication to any URI that isn’t in this list. Fortunately, Google supports using localhost as a valid URI, so you can test your application locally without having to worry about having a domain or public web server set up. The URIs in this list need to be explicit – include any port number (IIS Express as part of Visual Studio Express for Web doesn’t use port 80) and other information in your URI. For instance, a valid URI might look something like http://localhost:6250/login.aspx. The URIs in this list should be the pages that are actually processing the data Google returns once the user has authorized your application.
One thing to note: unless you need additional information or access to other APIs (like Gmail or Calendar), you should only ask for the user’s email address. Users are much less likely to authorize applications that want to do anything with their accounts that isn’t necessary.
Now that we’ve got the Google side of things created, we can actually create our login URL. This is really straightforward, and Google has fairly decent documentation on how the URL should be formatted. I’m not going to copypasta Google’s documentation. What I want to cover here is the state querystring variable. Unlike the other arguments sent to the Google login service, the state value can literally be anything you want it to be. As our first step in verifying the login data hasn’t been tampered with, we’re going to use state to hold a randomly-generated session ID. Later on, when we validate the data Google returns, we can compare the returned session ID with the real session ID.
First, off, when the user loads the login page (or the main page, if the link to Google’s login service is there), we need to see if a session ID for Google login is present. If not, we’re going to create one. I opted to use C#’s built-in GUID class to accomplish this. My session variable is simply called state, for the sake of simplicity.
protected void Page_Load(object sender, EventArgs e)
//when the page loads, a random session token needs to be created
//this will be sent to Google to verify that the data hasn't been tampered with
//create a random GUID as a token for preventing CSS attacks
//this only happens if a session doesn't already exist
if (Session["state"] == null)
Session["state"] = Guid.NewGuid();
Whether you want to use an image, a form input button, or a straight text link, your URL needs to include this session ID. On the webpage, your URL will look something like this:
When the user clicks this URL, it will direct them to either login to Google (if they’re not already logged in) or authorize your application to use their credentials and information. As soon as the user tells Google it’s okay for your application to use their information, they’ll be taken back to whatever URI is in the redirect_uri section of the above URL. From there, we’re going to do steps two and three – process the data and verify its integrity.