Click here to Skip to main content
15,887,135 members
Articles / Web Development / ASP.NET
Tip/Trick

Guide for Custom Google Login in MVC Without Default Identity

Rate me:
Please Sign up or sign in to vote.
4.43/5 (4 votes)
26 May 2017CPOL1 min read 16.2K   4   8
Guide for custom Google login in MVC without default Identity

Introduction

This article is a guideline for create custom login with Google in MVC application.
We can create this without using default Identity codes given by template. This is a very simple approach.

You can download or fork this project from Github:

Pre Request

Obtain a Google app key and secret. Follow the instructions here.

Set callback URL to http://localhost:3002/GoogleLoginCallback.

Follow Steps

Create one MVC application with no Authentication Selected.

Now follow these steps:

1. Install Required Packages

Install-Package Microsoft.Owin.Security.Google // Google Oauth provider
Install-Package Microsoft.Owin.Host.SystemWeb //For GetOwinContext() method
Install-Package Microsoft.Owin.Security.Cookies //For CookieAuthenticationDefaults.AuthenticationType

2. Configuration

  1. Add Owin Startup Class file "Startup.cs" in route folder of application, if it does not already exist. Then add a class file in App_Data folder with name Startup.Auth.cs.
  2. Add the following code in Startup.Auth.cs file:
    C#
    using Microsoft.Owin;
    using Microsoft.Owin.Security;
    using Microsoft.Owin.Security.Cookies;
    using Microsoft.Owin.Security.Google;
    using Owin;
    
    public partial class Startup {
    
      public void ConfigureAuth(IAppBuilder app) {
        app.SetDefaultSignInAsAuthenticationType
        (CookieAuthenticationDefaults.AuthenticationType);
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
          LoginPath = new PathString("/Account/Index"),
          SlidingExpiration = true
        });
        app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions()
        {
         ClientId = "Your Client ID",
         ClientSecret = "Your Secret Key" ,
         CallbackPath = new PathString("/GoogleLoginCallback")
        });
      }
    }
    
  3. Update Startup.cs file as follows:
    C#
    public partial class Startup{
     public void Configuration(IAppBuilder app)
     {
      ConfigureAuth(app); // For more information on how to configure your application,
                          // visit http://go.microsoft.com/fwlink/?LinkID=316888
     }
    }
    

    Note: Both files must be in the same namespace and partial class.

3. ViewModel and Database

  1. Create GoogleLogin ViewModel Class like this:
    C#
     public class GoogleLoginViewModel
     {
       public string emailaddress { get; set; }
       public string name { get; set; }
       public string givenname { get; set; }
       public string surname { get; set; }
       public string nameidentifier { get; set; }
    
       internal static GoogleLoginViewModel GetLoginInfo(ClaimsIdentity identity)
       {
         if(identity.Claims.Count() == 0 || identity.Claims.FirstOrDefault
         (x=> x.Type == ClaimTypes.Email) == null)
         {
           return null;
         }
         return new GoogleLoginViewModel
         {
           emailaddress = identity.Claims.FirstOrDefault
           (x => x.Type == ClaimTypes.Email).Value,
           name = identity.Claims.FirstOrDefault
           (x => x.Type == ClaimTypes.Email).Value,
           givenname = identity.Claims.FirstOrDefault
           (x => x.Type == ClaimTypes.GivenName).Value,
           surname = identity.Claims.FirstOrDefault
           (x => x.Type == ClaimTypes.Surname).Value,
           nameidentifier = identity.Claims.FirstOrDefault
           (x => x.Type == ClaimTypes.NameIdentifier).Value,
         };
       }
    }
    
  2. Create one database and add the following table in it:
    SQL
    CREATE TABLE [dbo].[UserAccount](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Email] [nvarchar](max) NOT NULL,
    [GivenName] [nvarchar](max) NULL,
    [Name] [nvarchar](max) NULL,
    [SurName] [nvarchar](max) NULL,
    [Identifier] [nvarchar](max) NOT NULL,
    [IsActive] [bit] NOT NULL,
    CONSTRAINT [PK_UserAccount] PRIMARY KEY CLUSTERED
    (
     [Id] ASC
    ) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, _
      ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
    GO
    
  3. Create one Edmx file and add the above table in this edmx file. You can also use the code first approach if you wish.

4. Changes in Account Controller

Create one AccountController class and add the following namespaces:

C#
using Microsoft.Owin.Security.Cookies;
using System.Security.Claims;
using Microsoft.Owin.Security;
  1. Default Page for login:
    C#
    public ActionResult Index() {
      return View();
    }
    
  2. Create View as follows:
    HTML
     @{
        ViewBag.Title = "Index";
      }
    
    <h2>Login</h2>
    
    <div style="margin-top:20px">&nbsp;</div>
    
    <div class="row" style="margin-top:20px;">
    <div class="col-md-5">
    <p><a class="btn btn-default btn-block" 
    href="@Url.Action(" signin="">
    &nbsp;&nbsp;Login using Google</a></p>
    </div>
    </div>    
  3. Add Sign in method:
    C#
    public void SignIn(string ReturnUrl = "/", string type = "")
    {
      if (!Request.IsAuthenticated)
      {
       if (type == "Google")
       {
        HttpContext.GetOwinContext().Authentication.Challenge(new AuthenticationProperties
                         { RedirectUri = "Account/GoogleLoginCallback" }, "Google");
       }
      }
    }
    
  4. Then create a method for GoogleSignIn Call Back:
    C#
    [AllowAnonymous]
    public ActionResult GoogleLoginCallback()
    {
     var claimsPrincipal = HttpContext.User.Identity as ClaimsIdentity;
     var loginInfo = GoogleLoginViewModel.GetLoginInfo(claimsPrincipal);
     if (loginInfo == null)
     {
       return RedirectToAction("Index");
     }
     MovieEntities db = new MovieEntities();
     var user = db.UserAccounts.FirstOrDefault(x => x.Email == loginInfo.emailaddress);
     if (user == null)
     {
      user = new UserAccount
      {
       Email = loginInfo.emailaddress,
       GivenName = loginInfo.givenname,
       Identifier = loginInfo.nameidentifier,
       Name = loginInfo.name,
       SurName = loginInfo.surname,
       IsActive = true
      };
      db.UserAccounts.Add(user);
      db.SaveChanges();
     }
     var ident = new ClaimsIdentity(
       new[] {
        // adding following 2 claim just for supporting default antiforgery provider
        new Claim(ClaimTypes.NameIdentifier, user.Email),
        new Claim
          ("http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider",
                     "ASP.NET Identity",
                     "http://www.w3.org/2001/XMLSchema#string"),
        new Claim(ClaimTypes.Name, user.Name),
        new Claim(ClaimTypes.Email, user.Email),
        // optionally you could add roles if any
        new Claim(ClaimTypes.Role, "User")
     },
     CookieAuthenticationDefaults.AuthenticationType);
     HttpContext.GetOwinContext().Authentication.SignIn(
     new AuthenticationProperties { IsPersistent = false }, ident);
     return Redirect("~/");
    }
    

5. Validate

  1. Add the following line in your layout page:
    C#
      @if (User.Identity.IsAuthenticated)
      {
       <ul class="nav navbar-nav navbar-right">
         <li><a href="#">@User.Identity.Name</a></li>
      </ul>
    }
    
  2. Create one controller as shown below to validate login:
    C#
    [Authorize]
    public class UsersController : Controller
    {
      // GET: Users
      public ActionResult Index()
      {
        WebEntities db = new WebEntities();
        var list = db.UserAccounts.ToList();
       return View(list);
      }
    }
    

Thanks friends! This is my first article. Hope you will like it. Please write comments if you have any doubts.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Lumen21
India India
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionGoogle Response Issue Pin
Member 1520050114-May-21 23:19
Member 1520050114-May-21 23:19 
QuestionNice Pin
Alen Toma13-Oct-18 15:27
Alen Toma13-Oct-18 15:27 
QuestionAbout claimsPrincipal Pin
Member 1387967519-Jun-18 23:52
Member 1387967519-Jun-18 23:52 
AnswerRe: About claimsPrincipal Pin
Member 1520050114-May-21 23:20
Member 1520050114-May-21 23:20 
QuestionFacebook Login Pin
ArvinPillaai19-Apr-18 2:39
ArvinPillaai19-Apr-18 2:39 
Praisenice work. Pin
dotnetclassic8-Jan-18 16:05
dotnetclassic8-Jan-18 16:05 
QuestionNice explanation but how we can signout from it ? Pin
prashantniku25-Jun-17 2:25
prashantniku25-Jun-17 2:25 
AnswerRe: Nice explanation but how we can signout from it ? Pin
Kishan K Choudhary27-Jun-17 23:08
professionalKishan K Choudhary27-Jun-17 23:08 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.