Google external login setup in ASP.NET Core

By Valeriy Novytskyy and Rick Anderson

Legacy Google+ APIs have been shut down as of March 7, 2019. Google+ sign in and developers must move to a new Google sign in system. The ASP.NET Core 2.1 and 2.2 packages for Google Authentication have be updated to accommodate the changes. For more information and temporary mitigations for ASP.NET Core, see this GitHub issue. This tutorial has been updated with the new setup process.

This tutorial shows you how to enable users to sign in with their Google account using the ASP.NET Core 2.2 project created on the previous page.

Create a Google API Console project and client ID

  • Navigate to Integrating Google Sign-In into your web app and select CONFIGURE A PROJECT.
  • In the Configure your OAuth client dialog, select Web server.
  • In the Authorized redirect URIs text entry box, set the redirect URI. For example, https://localhost:5001/signin-google
  • Save the Client ID and Client Secret.
  • When deploying the site, register the new public url from the Google Console.

Store Google ClientID and ClientSecret

Store sensitive settings such as the Google Client ID and Client Secret with the Secret Manager. For the purposes of this tutorial, name the tokens Authentication:Google:ClientId and Authentication:Google:ClientSecret:

dotnet user-secrets set "Authentication:Google:ClientId" "X.apps.googleusercontent.com"
dotnet user-secrets set "Authentication:Google:ClientSecret" "<client secret>"

When working with hierarchical keys in environment variables, a colon separator (:) may not work on all platforms (for example, Bash). A double underscore (__) is supported by all platforms and is automatically replaced by a colon.

You can manage your API credentials and usage in the API Console.

Configure Google authentication

Add the Google service to Startup.ConfigureServices:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(
            Configuration.GetConnectionString("DefaultConnection")));
    services.AddDefaultIdentity<IdentityUser>()
        .AddDefaultUI(UIFramework.Bootstrap4)
        .AddEntityFrameworkStores<ApplicationDbContext>();

    services.AddAuthentication()
        .AddGoogle(options =>
        {
            IConfigurationSection googleAuthNSection = 
                Configuration.GetSection("Authentication:Google");

            options.ClientId = googleAuthNSection["ClientId"];
            options.ClientSecret = googleAuthNSection["ClientSecret"];
        });

    services.AddMvc()
        .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

The call to AddIdentity configures the default scheme settings. The AddAuthentication(String) overload sets the DefaultScheme property. The AddAuthentication(Action<AuthenticationOptions>) overload allows configuring authentication options, which can be used to set up default authentication schemes for different purposes. Subsequent calls to AddAuthentication override previously configured AuthenticationOptions properties.

AuthenticationBuilder extension methods that register an authentication handler may only be called once per authentication scheme. Overloads exist that allow configuring the scheme properties, scheme name, and display name.

Sign in with Google

  • Run the app and click Log in. An option to sign in with Google appears.
  • Click the Google button, which redirects to Google for authentication.
  • After entering your Google credentials, you are redirected back to the web site.

Forward request information with a proxy or load balancer

If the app is deployed behind a proxy server or load balancer, some of the original request information might be forwarded to the app in request headers. This information usually includes the secure request scheme (https), host, and client IP address. Apps don't automatically read these request headers to discover and use the original request information.

The scheme is used in link generation that affects the authentication flow with external providers. Losing the secure scheme (https) results in the app generating incorrect insecure redirect URLs.

Use Forwarded Headers Middleware to make the original request information available to the app for request processing.

For more information, see Configure ASP.NET Core to work with proxy servers and load balancers.

Multiple authentication providers

When the app requires multiple providers, chain the provider extension methods behind AddAuthentication:

services.AddAuthentication()
    .AddMicrosoftAccount(microsoftOptions => { ... })
    .AddGoogle(googleOptions => { ... })
    .AddTwitter(twitterOptions => { ... })
    .AddFacebook(facebookOptions => { ... });

See the GoogleOptions API reference for more information on configuration options supported by Google authentication. This can be used to request different information about the user.

Change the default callback URI

The URI segment /signin-google is set as the default callback of the Google authentication provider. You can change the default callback URI while configuring the Google authentication middleware via the inherited RemoteAuthenticationOptions.CallbackPath property of the GoogleOptions class.

Troubleshooting

  • If the sign-in doesn't work and you aren't getting any errors, switch to development mode to make the issue easier to debug.
  • If Identity isn't configured by calling services.AddIdentity in ConfigureServices, attempting to authenticate results in ArgumentException: The 'SignInScheme' option must be provided. The project template used in this tutorial ensures that this is done.
  • If the site database has not been created by applying the initial migration, you get A database operation failed while processing the request error. Select Apply Migrations to create the database, and refresh the page to continue past the error.

Next steps

  • This article showed how you can authenticate with Google. You can follow a similar approach to authenticate with other providers listed on the previous page.
  • Once you publish the app to Azure, reset the ClientSecret in the Google API Console.
  • Set the Authentication:Google:ClientId and Authentication:Google:ClientSecret as application settings in the Azure portal. The configuration system is set up to read keys from environment variables.