How to integrate Google login feature in ASP.NET Core Identity

How to integrate Google login feature in ASP.NET Core Identity

Third-Party Authentications like Google, Facebook, Microsoft and Twitter are easy to perform in ASP.NET Core Identity. Here I will create a feature that will allow users to Login to Identity with Google credentials.

There are 2 main steps to do when creating Google login feature.

  • 1. Create a new Project in Google Console.
  • 2. Use Google APIs to communicate with your Project located in Google Console.

Create a new Project in Google Console

Google Console, is the place where you can create your Google Projects.

The first step is to create a new Project in Google Console, which you can do from this URL. Give your project a name like Google Log In and click CREATE button, this is shown in the below image:

create project in google console

After a few seconds, your project will be created, and you will be taken to the Project Dashboard page. In this page, on the top left corner, you will find the navigation menu. Click this menu and select APIs & Services ➤ Credentials. Check the below image for understanding:

create project credentials in google console

You will now reach Credentials Page where you will be asked to create your credentials. Here you will need to create your OAuth Client ID.

So, click the Create Credentials button, and then on the options that open up, click the OAuth client ID like shown in the image below:

create oauth client id

Next, you will be asked to Configure consent screen. So click on the Configure consent screen button, as shown by below image:

configure consent screen

Next, you will reach OAuth Consent Screen where you need to give your application a name. Then click the Save button. Check the below image:

Oauth consent screen

Next, you will be taken to the Create OAuth client ID page. In this page do the following things:

  • 1. For Application type option, select Web application.
  • 2. Give the name field some value
  • 3. On the Authorised redirect URIs field give 2 urls:
https://localhost:44395/Account/GoogleResponse
https://localhost:44395/signin-google

Note: these URLs will be different in your case based on your localhost port or domain. Next click the Create button once you are done.

You will also like to read more about the Full Working of Controllers in ASP.NET Core with lots of examples

This is shown in the below image:

create oauth client id

Authorized redirect URIs contains the URL of your application to which Google will redirect users after they are authenticated.

If you are using development mode then change the port number to your application’s port, else if you are in production make sure to use the domain name instead of localhost.

For the URL – /Account/GoogleResponse, I will create an action method called GoogleResponse in AccountController of my project.

The URL – /signin-google, is the default URL set by ASP.NET Core Identity for Google OAuth.

On clicking the Create button, you will now get your Client Id and Secret displayed in a window (see below image). Save them in a secure place, as you will be making Google API calls using these.

oauth client id secret

If you are dealing with OAuth for the first time, then consider it as an authentication procedure to authenticate users with your application using their Google credentials.

On successful authentication, Google will provide a token to your application, by using this token you can make API calls to Google.

The OAuth Client ID is created, now you have to enable the Google+ API. On the same page you will see Google APIs logo, click on it to reach the Google APIs Dashboard. Check the below image:

google apis page

On the Google APIs Dashboard, click the ENABLE APIS AND SERVICES button, as shown in the below image:

enable apis and services

On the Next page you have to find Google+ API. To do this, on the search box type Google+, then when you get the Google+ API result, simply click on it. Check the image below:

find google+ api

You will now reach the Google+ API page. All you have to do is enabling it. So, click on the Enable button and you are now ready to work. Check the below image:

enable google+ api
Ads: In case you’re interested in knowing more info on charter fishing jupiter fl, stop by https://reeleseafishingcharters.com

Communicate with your Project in Google Console

ASP.NET Core Identity has a built in support for authentication service that works on OAuth like Google, Facebook, Microsoft, LinkedIn, Twitter, etc. There are extension methods to register them in your application.

First you need to install the package called Microsoft.AspNetCore.Authentication.Google from NuGet.

Next, go to your Startup.cs file, and inside it’s ConfigureServices() method, set up the Google Authentication Service and provide the OAuth credentials you got from the Google Project before.

The code is shown in highlighted way.

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<AppIdentityDbContext>(options => options.UseSqlServer(Configuration["ConnectionStrings:DefaultConnection"]));
    services.AddIdentity<AppUser, IdentityRole>().AddEntityFrameworkStores<AppIdentityDbContext>().AddDefaultTokenProviders();

    services.AddAuthentication()
        .AddGoogle(opts =>
        {
            opts.ClientId = "717469225962-3vk00r8tglnbts1cgc4j1afqb358o8nj.apps.googleusercontent.com";
            opts.ClientSecret = "babQzWPLGwfOQVi0EYR-7Fbb";
            opts.SignInScheme = IdentityConstants.ExternalScheme;
        });

    services.AddControllersWithViews();
}

Note: The IdentityConstants class resides inside the Microsoft.AspNetCore.Identity namespace so you need to include this namespace in your Startup.cs class.

After the User is authenticated with Google OAuth then I will create the User’s Account in my Identity Database.

Earlier I added a User Validation that will only allow users with only yahoo.com email to be registered. This tutorial link is Creating Custom Username and Email Policy. Since Google user will have gmail.com email address therefore I need to disable this thing.

So go to the CustomUsernameEmailPolicy class and disable this thing as shown below:

using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Identity.Models;
using Microsoft.AspNetCore.Identity;

namespace Identity.IdentityPolicy
{
    public class CustomUsernameEmailPolicy : UserValidator<AppUser>
    {
        public override async Task<IdentityResult> ValidateAsync(UserManager<AppUser> manager, AppUser user)
        {
            IdentityResult result = await base.ValidateAsync(manager, user);
            List<IdentityError> errors = result.Succeeded ? new List<IdentityError>() : result.Errors.ToList();

            if (user.UserName == "google")
            {
                errors.Add(new IdentityError
                {
                    Description = "Google cannot be used as a user name"
                });
            }

            /*if (!user.Email.ToLower().EndsWith("@yahoo.com"))
            {
                errors.Add(new IdentityError
                {
                    Description = "Only yahoo.com email addresses are allowed"
                });
            }*/

            return errors.Count == 0 ? IdentityResult.Success : IdentityResult.Failed(errors.ToArray());
        }
    }
}

Next, go to the Login View of the Account Controller and add the link that enables user to log in with Google. See the highlighted code of the Login View:

@model Login

<h1 class="bg-info text-white">Login</h1>
<div class="text-danger" asp-validation-summary="All"></div>

<form asp-action="Login" method="post">
    <input type="hidden" asp-for="ReturnUrl" />
    <div class="form-group">
        <label asp-for="Email"></label>
        <input asp-for="Email" class="form-control" />
    </div>
    <div class="form-group">
        <label asp-for="Password"></label>
        <input asp-for="Password" class="form-control" />
    </div>
    <button class="btn btn-primary" type="submit">Log In</button>
    <a class="btn btn-info" asp-action="GoogleLogin">Log In With Google</a>
</form>

The new link targets the GoogleLogin action on the Account controller. You can see this action along with the changes I made to the Account controller (code is given below). Basically I added 2 method which are GoogleLogin & GoogleResponse.

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Identity.Models;
using System.Threading.Tasks;
using System.Security.Claims;

namespace Identity.Controllers
{
    [Authorize]
    public class AccountController : Controller
    {
        private UserManager<AppUser> userManager;
        private SignInManager<AppUser> signInManager;

        public AccountController(UserManager<AppUser> userMgr, SignInManager<AppUser> signinMgr)
        {
            userManager = userMgr;
            signInManager = signinMgr;
        }

        // other methods

        public IActionResult AccessDenied()
        {
            return View();
        }

        [AllowAnonymous]
        public IActionResult GoogleLogin()
        {
            string redirectUrl = Url.Action("GoogleResponse", "Account");
            var properties = signInManager.ConfigureExternalAuthenticationProperties("Google", redirectUrl);
            return new ChallengeResult("Google", properties);
        }

        [AllowAnonymous]
        public async Task<IActionResult> GoogleResponse()
        {
            ExternalLoginInfo info = await signInManager.GetExternalLoginInfoAsync();
            if (info == null)
                return RedirectToAction(nameof(Login));

            var result = await signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, false);
            string[] userInfo = { info.Principal.FindFirst(ClaimTypes.Name).Value, info.Principal.FindFirst(ClaimTypes.Email).Value };
            if (result.Succeeded)
                return View(userInfo);
            else
            {
                AppUser user = new AppUser
                {
                    Email = info.Principal.FindFirst(ClaimTypes.Email).Value,
                    UserName = info.Principal.FindFirst(ClaimTypes.Email).Value
                };

                IdentityResult identResult = await userManager.CreateAsync(user);
                if (identResult.Succeeded)
                {
                    identResult = await userManager.AddLoginAsync(user, info);
                    if (identResult.Succeeded)
                    {
                        await signInManager.SignInAsync(user, false);
                        return View(userInfo);
                    }
                }
                return AccessDenied();
            }
        }
    }
}

The GoogleLogin method creates a redirectUrl variable that contains the URL of the GoogleResponse action method, it then uses the signInManager.ConfigureExternalAuthenticationProperties() method to configures the redirect URL (to the ‘redirectUrl’ value) and user identifier for the Google Authentication. The associated code for this is:

string redirectUrl = Url.Action("GoogleResponse", "Account");
var properties = signInManager.ConfigureExternalAuthenticationProperties("Google", redirectUrl);

Finally, it is redirecting user to the Google OAuth URL using the below code:

return new ChallengeResult("Google", properties);

After authenticating user, Google will redirect them to the GoogleResponse action method. Inside this method I get the details of the User’s Google account using the code shown below:

ExternalLoginInfo info = await signInManager.GetExternalLoginInfoAsync();

The ExternalLoginInfo class defines an ExternalPrincipal property that returns a ClaimsPrincipal object. It contains the claims provided for the user by Google. Next, I sign the user to my Application using these claims, see the below code:

var result = await signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, false);

If the sign-in fails, then it is due to the fact that there is no user in the database that represents the Google user. I solve this by creating the new user and associating the Google credentials with it. See the below code that do this work:

IdentityResult identResult = await userManager.CreateAsync(user);
identResult = await userManager.AddLoginAsync(user, info);

The Name and Email of the user is returned to the View using the code:

string[] userInfo = { info.Principal.FindFirst(ClaimTypes.Name).Value, info.Principal.FindFirst(ClaimTypes.Email).Value };
return View(userInfo);

And finally the view file called GoogleResponse.cshtml shows the user details. It’s code is given below.

@model IEnumerable<string>
 
<h1 class="bg-info text-white">Your Login Details</h1>
 
<table class="table table-sm table-bordered">
    <tr><th>Name</th><th>Email</th></tr>
    <tr>
        @foreach (string info in Model)
        {
            <td>@info</td>
        }
    </tr>
</table>
Testing the Log In with Google

Run your project and go to the Login URL – /Account/Login, where you will see the Log In With Google button, as shown by the image given below:

login with google button

Click the Log In With Google button, and this will start the Google Authentication Process, where you will be asked to Sign in with your Google account, as shown by the image below:

sign in with google

Select your Google Account and enter the password, as shown in the below image:

enter google password

Once the Google Authentication is completed, you will be redirected to your application and you will see your Google account details. Check the below image:

google details of the user

Multiple authentication providers

When the app requires multiple providers then chain the provider extension methods behind AddAuthentication method:
services.AddAuthentication()
    .AddMicrosoftAccount(microsoftOptions => { ... })
    .AddGoogle(googleOptions => { ... })
    .AddTwitter(twitterOptions => { ... })
    .AddFacebook(facebookOptions => { ... });

You can download the full codes of this tutorial from the below link:

Download

Conclusion

Now you have learned to integrate Google Login in Identity. In the same way you can also use external authentication providers like Facebook, Twitter, Linked and Microsoft to.

Share this article -

yogihosting

ABOUT THE AUTHOR

This article has been written by the Technical Staff of YogiHosting. Check out other articles on "ASP.NET Core, jQuery, EF Core, SEO, jQuery, HTML" and more.