Logging In: Google Authentication Using OAuth2 and ASP.NET C#

Previously, I covered an overview of how Google’s OAuth2 API works, as well as the initial URL and session data used to direct the user to Google’s login service. Google has documentation on the next steps of the login process, but I found it difficult to follow and somewhat unclear from a development perspective. However, for reference, Google’s own documentation used for this article can be found here. The steps I’m going to cover in this article are as follows:

  • Verify the data received from Google via the login URL
  • Send the authorization token to Google’s authentication service
  • Parse the response data

The validation portion of the process is going to be in the third article in this series, particularly because the cryptography aspect of it is somewhat complex (but not scary!). Hit the jump to get started.

Verifying Initial Google Response

When the user clicks your login button or link and authorizes your application, Google will redirect the user back to your site. The redirect URL contains querystring data that can be used to verify the login session and access Google’s APIs. The two querystring elements we are concerned with are state and code. When Google redirects back to your site, state will contain the value you passed through your original login link. If you followed my last piece in this series, this value will be the GUID generated when your login page originally loaded. This should still be present in your user’s session in your application. The other value, code, is a one-time authorization code provided by Google. This is what you’ll use to actually get your user’s information from Google’s authentication service. First, in the code for the login page (login.aspx in this example), I’m going to set all the variables for the request to be sent to Google’s API.

Obviously, you’ll need to set client_id and client_secret to the data in the Google Developer Console for your own application. Next, we need to verify that a code value actually exists in the URL and that the user isn’t already logged in. I’m using a session variable called loggedin for this purpose.

The gurl variable contains the data that will be passed back to Google via a POST request. I’m taking the code from what I created for testing purposes, so I’m using Response.Write to output the information Google passes back throughout the process. In the code above, this also checks to see if the user is logged in, or if the page being loaded doesn’t contain a code (Google’s authorization code). In those cases, we can just skip the whole login process entirely.

That state session ID is also validated, as the first step in ensuring the integrity of the data sent back from Google. The value of state in the querystring data Google returned needs to match the session ID generated when the page loaded. If it doesn’t match, that can indicate that either the session in your application expired or the data passed back from Google was modified. This alone is not adequate for ensuring data integrity, however! It’s just one of several steps.

The function that will handle all of the requests and validation is called gLogin.

To recap so far:

  1. Our application generates a unique session ID.
  2. The user clicks a login link or button.
  3. Our application directs the user to a Google page, including the session ID in the page URL.
  4. The user logs into Google with their credentials.
  5. The user authorizes our application to use their Google account information – namely, their email address.
  6. Google redirects the user back to our application, including the unique session ID and a one-time authorization code in our application’s URL.
  7. Our application checks two things:
    • Does an access token exist in the URl querystring?
    • Is the user already logged in?
  8. If the user is not logged in and an access token exists in the URL querystring, we can proceed with requesting information from Google about the user.

We’re not even close to being done yet – time to keep going!

Sending the POST Request to Google

The authorization code Google provides allows your application to access basic information about the user. Your application uses an HTTPS POST request to access Google’s APIs. This ensures the connection is encrypted. Additionally, this request is done server-side, so the user – or malicious third-parties – can’t intercept the request and change it (or steal your user’s information).

In the code above, we created a string of parameters to be sent to Google. This is passed to a function, gLogin, to be used in the request to Google. Let’s look at what that function does.

Before we do anything, there are several libraries that need to be included in the application.

Now that we’ve included everything we need (along with the default libraries included in every new code behind page in an ASP.NET project), we can go ahead and get the user’s information from Google.

The first part is pretty straightforward – pass arguments to Google’s OAuth2 service using the one-time authorization code we’ve already obtained from Google. This is done using the HttpWebRequest class. For your reference, the MSDN documentation on this class is here. Google provides documentation on the format of the POST request, as well as details on the data that’s returned, here.

This request asks Google for the user’s information, and Google returns a JSON array including two important bits – an access token and an ID token. If your application needs to access any of Google’s APIs, you’ll need the access token. However, if you’re only using the user’s Google account for login purposes, all you need is the ID token.

The ID token is a JWT, or JSON Web Token. There is extensive documentation on what a JWT is and how it’s used. If you’re the document-reading type, you can peruse the OpenID consortium’s documentation on the subject. On the other hand, if you’re just trying to make Google authentication work, you’re in luck – I did all the research for you! Go me!

First, we’re going to make a class to hold Google’s JSON array. This will make it a bit easier to pull out the bits of data we need – namely, the ID token.

We can use this class with the JavaScriptSerializer class that is part of .NET. MSDN, as always, has great documentation on how to use this class. We’re going to use this class to create an instance of gLoginInfo containing Google’s JSON response.

Now, all we actually care about is the id_token member of our gLoginInfo instance, called gli, since that’s the JWT containing the logged-in user’s information. Per the documentation, this is a period-delimited string containing three sections. The first two are Base64-encoded JSON arrays. The third is a SHA-256 hash of the first two segments, signed with Google’s public certificate. That part is going to be the third article in this series.

The Split() string function will put this into an array so that we can decode each segment individually.

Decoding a Base64 string in C# actually results in a byte array rather than a plain string, even if the decoded data is a string. Because of this, the easiest thing to do is write a separate function that will take an inputting Base64 string, decode it, and convert the byte array into a string to use with the JavaScriptSerializer class.

This is a modified version of code I found in this forum thread. C# is really picky about Base64-encoded data, and the string passed to Convert.FromBase64String() needs to be a character length that is a whole number multiple of 4. The Base64 spec accommodates this by allowing an equals sign (=) to be used as padding at the end of an encoded string. With this requirement in mind, I added a bit of code before the actual decoding portion to add padding.

What we’re going to focus on right now is the second segment – the JWT payload, which is a JSON array. Google provides documentation on the elements in the payload and what they’re used for. First thing we need is a class containing the elements in the decoded payload.

Now we can use our Base64 decoding function and our gLoginClaims class to decode the JWT payload.

At this point, you can use the decoded JSON array to add your user’s information to your application’s database, or to log in existing users. The values you want to focus on are sub and email. Because a user can change the email address associated with their Google account, it’s not a reliable unique identifier for that user account. The sub value, per Google’s documentation, is a unique identifier for that Google account.

This isn’t a simple process, as you can see. However, once the process is clearly detailed, it’s a lot easier to understand.

The last article in this series will cover the cryptographic signature used to verify the user data provided by Google.

Part one of this series is available here.
Part three of this series is available here.

3 thoughts on “Logging In: Google Authentication Using OAuth2 and ASP.NET C#

  1. Pingback: A Better Geek :: The Big Picture: Google Authentication Using OAuth2 and ASP.NET C#

  2. Pingback: A Better Geek :: Getting Started: Google Authentication Using OAuth2 and ASP.NET C#

  3. Goran

    yours article is great, but i have problem in this second step when get authorization code using :

    I do get ‘code’ from google after all steps, and my page was opened like :


    But when try to use that ‘code’ for get ‘access token ‘and execute POST to https://accounts.google.com/o/oauth2/v2/token
    like you wrote
    string grant_type = “authorization_code”;
    “code=” + /*current.Server.UrlEncode(code)*/code + “&client_id=” + client_id +
    “&client_secret=” + client_secret + “&redirect_uri=” + /*current.Server.UrlEncode(redirect_uri)*/ redirect_uri + “&grant_type=” + grant_type

    , i do get exception with message ‘Error validating access token’.

    I did try to google it but nothing clear.
    Please if you have some hint or..
    Best regards,
    Goran Milosavljevic


Leave a Reply

Your email address will not be published. Required fields are marked *