BigBastis Blog

.NET

Using Google Open Auth Login in Asp.Net MVC Applications

Posted on .

Using Google Open Auth Login in Asp.Net MVC Applications

Introduction

.NET

Using Google Open Auth Login in Asp.Net MVC Applications

Posted on .

Introduction

Open Auth is everywhere, maybe you even read my article on how to retrieve calendar events from your google calendar using open auth. In this article i would like to show you a simple way to create an open auth login for your asp.net mvc website.

Basically you can just open up visual studio and create a new asp.net mvc project and select individual user as the authentication template. Visual studio will now create a new project template for you with working examples for Google, Facebook and Microsoft open auth login.
But as you’ll quickly notice this is a very complex example which is only good for authentication, so if you want to have different information about the user (i.e. his picture) or want to perform actions in his name (post to the wall in facebook) you’re out of luck.
This is where this article comes into play. We will create an authentification mechanism which will allow us to have additional rights next to simple authentication while keeping the codebase small and clean.

Token setup

Before you can start writing code you first need to create public and private keys to authenticate your application to google. I covered this topic at my last article, so if you dont have your tokens yet, just follow the link and read through the chapter „API Setup“. Afterwards continue here.

Communication overview

So lets have a look on the order of events which will take place in our application.

  • Our application gets called and checks if the authentication cookie is set. Since its the first call to our application the cookie is not present. The application redirects the user to the login page.
  • The login page offers the user to login using open auth with google as the provider. The user clicks on the link to login via google.
  • The click directs the user to the login url /auth/googlelogin
  • The API takes the user to the google consent screen (you neet to login to your google account first)
  • The user allows our application to access the requested information (basic user info) and is being redirected back to our application
  • Now we’re back in the auth/googlelogin method and can check wether the provided google informations are known to our database. If yes -> login, if no -> signup

Project setup

Open up Visual Studio and create a new Asp.Net MVC (5) project, be sure to select an empty project template without athentication to make sure we start with a clean codebase.

Create an empty MVC Project
New Project temaplate

Create a new (almost) empty MVC Project

Of course you need some kind of database to store your registered users. I won’t cover the topic of setting up a database in this article but i would recommend you to use EntityFramework in order to create a simple database very quickly without a lot of configuration.

Now we can begin to setup our authentication methods, but since we will be using the Google API for this we need to install the Google libraries first. Just start up the NuGet Package Manager Console and install the following packages:

Install-Package Google.Apis.Auth
Install-Package Google.Apis
Install-Package Google.Apis.Auth.Mvc
Install-Package Google.Apis.Plus.v1

NuGet will now download and add the libraries to our project. After NuGet is done you should have (among others) the following libraries under your project references:

Google.Apis
Google.Apis.Auth
Google.Apis.Auth.Mvc4
Google.Apis.Auth.PlatformServices
Google.Apis.Core
Google.Apis.PlatformServices
Google.Apis.Plus.v1

Just that you know, we don’t actually need the Plus.v1 package for successful authentication, but since i would like to know the users name, profile picture and other basic information i added this dependency too. Without this package we (as the application) would only get to know the google account id, which is the E-Mail Address by default. if this is enough for you just don’t add the last package to your project.

Authentication

First we need some Model to hold our user information which (if you use EntityFramework) also can be used as an Entity-Class to access the database. This could look something like this:

public class UserProfile
{
    [Required(ErrorMessage="Please tell us your name")]
    [DisplayName("Your name")]
    public string Name { get; set; }

    [Required(ErrorMessage = "Choose a displayname for you")]
    [DisplayName("Displayname")]
    public string DisplayName { get; set; }

    public string Picture { get; set; }

    [Required(ErrorMessage = "Please enter an E-mail address")]
    [DisplayName("E-Mail-Address")]
    [RegularExpression("([a-zA-Z0-9]+@[a-zA-Z0-9]+\.[a-zA-Z0-9]+)", 
        ErrorMessage = "Please provide a valid E-mail address")]
    public string Email { get; set; }

    [Key]
    [Required]
    public string UniqueId { get; set; }

    public IdentityProvider Provider { get; set; }
}

//maybe we will support more providers later ;)
public enum IdentityProvider
{
    Google = 0,
    Twitter = 1,
    Facebook = 2
}

Nothing special here, just some properties to hold the basic user information including some validation tags to make MVC do the dirty work.

Lets go ahead and create the AuthController with the GoogleLogin method:

public async Task<ActionResult> GoogleLogin(CancellationToken cancelToken)
{
    var result = await new AuthorizationCodeMvcApp(this, 
                    new GoogleAuth()).AuthorizeAsync(cancelToken);

    if (result.Credential == null)
        return new RedirectResult(result.RedirectUri);

    var plusService = new PlusService(new BaseClientService.Initializer
    {
        HttpClientInitializer = result.Credential,
        ApplicationName = "MyApp"
    });
	
    //get the user basic information
    Person me = plusService.People.Get("me").Execute();

    //check if the user is already in our database
    UserProfile account = _db.Users.FirstOrDefault(u => u.UniqueId.Equals(me.Id));
    if(account == null){
        //this is a new user -> register view
        UserProfile profile = new UserProfile(){
            Name = me.Name.GivenName + " " + me.Name.FamilyName,
            Email = me.Emails.ElementAt(0).Value,
            DisplayName = me.DisplayName,
            Picture = me.Image.Url,
            UniqueId = me.Id,
            Provider = IdentityProvider.Google
        };
        TempData["newProfile"] = profile; 
        return RedirectToAction("register", "account");
    }else{
        //this is a registered user -> login
    }
    return RedirectToAction("index", "home");
}

The important part is happening in the first lines of this Action-Method. We create a new AuthorizationCodeMvcApp and provide an new instance of GoogleAuth to it. The GoogleAuth Class extends the FlowMetadata Class provided by the Google API and overrides Flow property which provides the client secret and the needed app privileges to the API.

public class GoogleAuth : FlowMetadata
{
    private static readonly IAuthorizationCodeFlow flow =
        new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
        {
            ClientSecrets = new ClientSecrets
            {
                ClientId = "my-app-client-id.apps.googleusercontent.com",
                ClientSecret = "my-app-client-secret"
            },
            Scopes = new[] {
                PlusService.Scope.UserinfoEmail,
                PlusService.Scope.UserinfoProfile
            },
            DataStore = new FileDataStore("Google.Apis.Sample.MVC")
        });

    public override string GetUserId(Controller controller)
    {
        return "user1";
    }

    public override IAuthorizationCodeFlow Flow
    {
        get { return flow; }
    }
}

The Google API provides an own controller which is responsible for receiving the authentication response. In order to use it we need to provide our implementation of FlowMetadata (see above) to it:

public class AuthCallbackController :
        Google.Apis.Auth.OAuth2.Mvc.Controllers.AuthCallbackController
{
    protected override Google.Apis.Auth.OAuth2.Mvc.FlowMetadata FlowData
    {
        get { return new GoogleAuth(); }
    }
}

And thats basically it. Since the API is doing most of the heavy lifting of redirecting and receiving the callback we’re finished here. Just add a Db-Provider (i.e. EntityFramework) and some Views alongside with some Account-managing-Controller and you’re ready to go.

You can find a working web application using this example in my github repo.

profile

Sebastian Gross

http://www.bigbasti.com

Sebastian Gross arbeitet in Bielefeld als Softwareentwickler für .NET und Java im Bereich Web.Als Fan der .NET-Plattform lässt er sich kein Userguppen Treffen und Community Event im Raum OWL entgehen.Dabei hat er eine besondere Vorliebe für das ASP.NET MVC Framework und für das Test Driven Development (TDD) entwickelt.

There are no comments.

Kommentar verfassen

View Comments (0) ...
Navigation