Implementing Google Authentication in an ASP.NET Core 2.0 App

As modern web applications evolve to be more interconnected and support a wider array of integration scenarios, authentication and identity management have become increasingly important concerns. Users expect seamless single sign-on (SSO) experiences and the ability to leverage their existing social media or enterprise accounts.

ASP.NET Core provides a flexible and extensible authentication system that supports various identity providers and authentication schemes out of the box. Developers can easily add support for popular external login providers like Google, Facebook, Twitter, Microsoft Account, and more.

In this in-depth guide, we‘ll walk through the process of integrating Google authentication into an ASP.NET Core 2.0 web application. We‘ll explore the underlying OAuth 2.0 and OpenID Connect protocols, discuss security best practices, and cover advanced scenarios like retrieving additional user info and implementing a custom user registration flow.

Authentication in ASP.NET Core

ASP.NET Core provides a robust authentication system built on top of the popular OWIN/Katana middleware. It offers several authentication options:

  • Cookie-based authentication – The default authentication scheme in ASP.NET Core. After a user logs in, their identity is stored in an encrypted cookie. On subsequent requests, the cookie is validated to authenticate the user.

  • JWT Bearer authentication – Used for authenticating APIs. Clients include a JSON Web Token (JWT) in the Authorization header of HTTP requests. The server validates the token to authenticate the request.

  • External authentication providers – Allows users to log in with their existing accounts from third-party providers like Google, Facebook, Twitter, Azure AD, etc. Leverages OAuth 2.0 and OpenID Connect protocols.

  • Windows authentication – Authenticates users based on their Windows account in an intranet environment. Uses Kerberos or NTLM.

  • Custom authentication – Developers can create their own custom authentication scheme by implementing the IAuthenticationHandler interface.

In this guide, we‘ll focus on implementing external authentication with Google.

Why Google Authentication?

Google is one of the most widely-used authentication providers, with over 1.5 billion active Gmail users as of October 2019 (source). By allowing users to log in with their Google accounts, you can:

  • Simplify registration – Users don‘t need to create yet another account for your site. They can sign up with just a few clicks using their Google login.

  • Reduce friction – With fewer form fields to fill out and no new password to remember, users are more likely to complete the registration process.

  • Increase trust – Many users are wary of providing personal info to unfamiliar sites. Seeing a "Sign in with Google" button can increase user confidence that their data is safe.

  • Access additional user info – With the user‘s permission, you can access additional data from their Google profile like their name, profile picture, and email address. This can be used to personalize their experience in your app.

According to auth0‘s customer data, social logins now make up about 45% of all their logins, with Google being the most popular option (source). Adding "Login with Google" can help boost conversion rates and user engagement in your app.

How Google Authentication Works

Google authentication is based on the OAuth 2.0 and OpenID Connect (OIDC) protocols. Here‘s a simplified overview of how it works:

  1. The user clicks a "Sign in with Google" button in your app
  2. Your app redirects them to Google‘s OAuth 2.0 authorization endpoint
  3. The user logs in with their Google credentials and grants your app permission to access their info
  4. Google redirects the user back to your app with an authorization code
  5. Your app exchanges the authorization code for an ID token and access token
  6. Your app validates the ID token to confirm the user‘s identity
  7. The user is now authenticated and you can access their Google user info using the access token

The combination of OAuth 2.0 (for authorization) and OpenID Connect (for authentication) allows your app to securely authenticate users and access Google APIs on their behalf.

Registering your app with Google

To get started, you first need to create a new project in the Google API Console:

  1. Go to https://console.developers.google.com/
  2. Click "Select a project" and then "New Project"
  3. Enter a name for the project and click "Create"

Create a new project dialog

Next, configure the OAuth consent screen:

  1. Go to the "OAuth consent screen" tab
  2. Select "External" as the user type (unless you‘re authenticating corporate Google accounts)
  3. Fill out the app name, support email, and developer contact info
  4. Add any required scopes (e.g. profile, email, openid)
  5. Click "Save and Continue"

OAuth consent screen

Finally, create an OAuth client ID:

  1. Go to the "Credentials" tab and click "+ Create Credentials"
  2. Select "OAuth client ID"
  3. Choose "Web application" as the application type
  4. Enter a name for the client
  5. Add an authorized redirect URI for your app (e.g. https://localhost:5001/signin-google)
  6. Click "Create"

Create OAuth client

You should now have a client ID and client secret that you can use to configure Google authentication in your ASP.NET Core app.

Configuring Google Authentication in ASP.NET Core

With your Google API project set up, you can now add Google authentication to your ASP.NET Core app.

First, add the Microsoft.AspNetCore.Authentication.Google NuGet package to your project:

dotnet add package Microsoft.AspNetCore.Authentication.Google

Then in your Startup.ConfigureServices method, add the Google authentication service:

services.AddAuthentication(options =>
{
    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = GoogleDefaults.AuthenticationScheme;
})
.AddCookie()
.AddGoogle(options =>
{
    options.ClientId = Configuration["Google:ClientId"];
    options.ClientSecret = Configuration["Google:ClientSecret"];
});

This configures your app to use Google authentication with the client ID and secret stored in your appsettings.json file.

In your Startup.Configure method, add the authentication middleware:

app.UseAuthentication();
app.UseAuthorization();

Finally, in your login page or navigation bar, add a "Sign in with Google" button:

<a asp-controller="Account" 
   asp-action="ExternalLogin" 
   asp-route-provider="Google">Sign in with Google</a>

When clicked, this will initiate the Google OAuth flow and prompt the user to log in with their Google account. Upon successful authentication, they will be redirected back to your app.

Securing Authentication

When implementing Google authentication (or any external auth provider), it‘s important to follow security best practices to protect against common threats like cross-site request forgery (CSRF) and open redirector attacks.

Some key considerations:

  • Use HTTPS – Ensure your entire authentication flow takes place over secure HTTPS connections to prevent interception of sensitive tokens and user credentials.

  • Validate the ID token – After receiving an ID token from Google, validate it to confirm the token hasn‘t expired, hasn‘t been tampered with, and was issued by Google for your specific app.

  • Use a state parameter – Include an opaque state value in the initial authentication request and validate it in the callback to prevent CSRF attacks.

  • Verify redirect URIs – Whitelist the allowed redirect URIs for your app and reject any authentication requests containing an unrecognized redirect URI.

ASP.NET Core‘s Google authentication handler takes care of many of these details for you, but it‘s still important to be aware of the potential risks.

Retrieving User Info

Once a user has authenticated with Google, you can access additional details from their Google profile. Common user properties include:

  • name – The user‘s full name
  • email – The user‘s email address
  • picture – A URL to the user‘s profile picture
  • locale – The user‘s locale (e.g. "en")

To request access to this info, you need to include the appropriate scopes in your authentication request. The most common scopes for user info are:

  • openid – Required for any OpenID Connect request
  • profile – Basic profile info like name and profile picture
  • email – The user‘s email address

You can specify the scopes in the AddGoogle configuration:

.AddGoogle(options =>
{
    // ...
    options.Scope.Add("profile");
    options.Scope.Add("email");
})

After authentication, you can access the user‘s info in the ExternalLogin callback:

var info = await _signInManager.GetExternalLoginInfoAsync();
if (info == null)
{
    return RedirectToAction("Login");
}

var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false);
if (result.Succeeded) 
{
    var email = info.Principal.FindFirstValue(ClaimTypes.Email);
    var name = info.Principal.FindFirstValue(ClaimTypes.Name);
    var picture = info.Principal.FindFirstValue("picture");

    // TODO: Persist user info to database or session
    // ...

    return RedirectToAction("Index", "Home");
}

Here we retrieve the user‘s email, name, and profile picture from the authenticated principal. You could then persist this to a database to create a local user account associated with their Google login.

Frontend Integration with Angular

If you‘re building a single-page app (SPA) with a frontend framework like Angular, you can still leverage Google authentication using the Google Sign-In SDK.

First, add the Google Sign-In script tag to your index.html file:

<script src="https://apis.google.com/js/platform.js" async defer></script>

Then in your component or service, use the gapi object to initiate Google Sign-In:

ngOnInit() {
  gapi.load(‘auth2‘, () => {
    this.auth2 = gapi.auth2.init({
      client_id: ‘YOUR_CLIENT_ID.apps.googleusercontent.com‘,
      scope: ‘profile email‘
    });
  });
}

signIn() {
  this.auth2.signIn().then(user => {
    console.log(user);
    // TODO: Send ID token to backend to authenticate user
  });
}

When the user clicks the "Sign In" button, they will be prompted to log in with their Google account. Upon successful login, you will receive a GoogleUser object containing their ID token and access token.

You can then send the ID token to your ASP.NET Core backend to authenticate the user. The backend should validate the token, create a new user account if necessary, and return an authentication cookie or JWT token to the frontend.

For more details, see Google‘s docs on Integrating Google Sign-In into your web app.

Other Considerations

Some additional points to consider when implementing Google authentication:

  • Incremental authorization – Google supports incremental auth, allowing you to request additional scopes (e.g. access to Calendar or Drive) after a user has initially logged in. This can be useful for progressive enhancement of your app‘s features.

  • Custom consent screen – For G Suite users, you can customize the OAuth consent screen with your own logo and privacy policy. This can help provide a more seamless branding experience.

  • Refresh tokens – To access Google APIs when the user is offline, you need to request a refresh token during the initial authentication flow. You can then use this to generate new access tokens as needed.

  • Multi-tenancy – If you‘re building a multi-tenant app (e.g. a SaaS product), you may want to support authenticating users from different Google Workspace domains. You can configure this in the Google API Console under "OAuth 2.0 > Authorized domains".

  • Other Google APIs – Once a user has authenticated with Google, you can access a wide range of Google APIs on their behalf by including the appropriate scopes. Popular APIs include Google Calendar, Google Drive, Gmail, and Google Maps.

Conclusion

Integrating Google authentication into your ASP.NET Core app can significantly improve the user experience by allowing them to log in with their existing Google accounts. It provides a secure, standards-based way to authenticate users and access additional information from their Google profile.

In this guide, we covered the key aspects of implementing Google authentication, including:

  • Registering your app in the Google API Console
  • Configuring the Google authentication handler in ASP.NET Core
  • Securing the authentication flow with HTTPS and state validation
  • Retrieving additional user info like name and profile picture
  • Integrating with Angular using the Google Sign-In SDK

By understanding the underlying OAuth 2.0 and OpenID Connect protocols and following security best practices, you can build robust and secure authentication flows that leverage the power of Google‘s identity platform.

Some helpful resources for further reading:

Implementing Google authentication is just one piece of the larger identity and access management picture in modern web apps, but it‘s an important one that can help streamline the user experience and drive engagement. By offering users the convenience and security of logging in with their Google accounts, you can reduce friction in your registration process and build trust with your audience.

Similar Posts