Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

MVC and Identity Framework 2.0

0.00/5 (No votes)
22 Jan 2015 1  
How to use the new Identity framework with external authentication services such as Google, Facebook, Twitter and so forth, retrieving information from users profiles. Including NInject integration.

Introduction

Few months ago, I had to start a project that included most of the new features of MVC and different authentication methods. Identity framework 2.0 was just out the oven and I decided to use it because it's way more flexible than the previous version, more powerful and extensible. Unfortunately, all the new great Microsoft tools had a total lack of clear information about how to use them and it took me a couple of months to put all the pieces together and make it work. Now, there are tons of different articles online but none of them solve all the issues I had during this development process, so I decided to write this article to help everyone to create an MVC project with NInject, Identity Framework 2.0, WebApi (I realized it's way better to use the webapi even when I was creating two projects, WebApi and regular Web) and NInject.

Background

My intention is not to take credit for the great articles I've been following during my process. I will mention all of them through my articles.

I had to create two different websites that work together, an API consumed by mobile devices (iOS and Android) and a typical management website. I used authentication in both cases and it works perfectly.

In both cases, I had to pull some data from the different authentication processes and it was another problem to solve, there's no article that explains clearly how to do it and I solved this reading every single developer document of Facebook, Google Auth 2.0, Twitter and so forth. At the end, I could assemble all the parts and I created a great project that handles everything together.

The Web API

The Web API is an extension of the regular MVC controller but is much more powerful. There're some interesting new concepts on it. It still has the ability of handling every request in a normal MVC controller way but in case you want to build a REST API, you will find it more useful due to some of these concepts:

  • HTTP Actions are directly mapped to controller methods. It means a Get, Post, Put method will invoke exactly that method in case a mapping was not specified. GET /mycontroller/1 will invoke Get(long 1) on MyController
  • Built-in content negotiation, you don't have to worry about formats, they're negotiated internally by the Web API reading the content request and delivering XML or Json transparently
  • Can be hosted in a Windows Service

MVC Project

At the time of writing this article, there was no update for the Visual Studio templates or final release of MVC Identity Framework 2.0. I've tried to find it more than once but the pre-release is still there and it's the only one available. Even when it works with a non-empty MVC project, it's much better to always create an empty project instead of a specific one (Basic, WebApi, Internet Application and so forth) if we're going to build a website. WebApi project works well anyway in case you need an API project but the sample templates are going to replace many of the features of any of these projects.

It works with MVC 4 and MVC 5, I didn't have time to test it with MVC 6 yet. I will write a new article about it when I have enough time to evaluate it.

I'm using Visual Studio 2013 for this sample:

  1. Go to File -> New Project and Choose Visual Studio 2012. Remember to select .NET Framework 4.5.1 to see all the templates, choose ASP.NET MVC 4 Web Application, don't worry it says "MVC 4", it's only the basic template, you can pull everything from NuGet in case you want MVC 6 for example.

    Image 1

  2. Choose the empty project template. Do not worry about unit test now. Select Razor View engine, if you're not using Razor, this is a good time to start!

    Image 2

    Once the project has been created, you have to install a NuGet package that does the magic of creating everything into your new project.

  3. Go to Tools -> NuGet Package Manager -> Packet Manager Console (Hint: It's a tab on the bottom of Visual Studio, you can just click it.)
    Install-Package Microsoft.AspNet.Identity.Samples -Pre

    Your project folder structure is going to be modified by this command, in fact if you have some files opened like Web.Config, you will be prompted several times to refresh your file due to all the changes. Pay attention to the Console because you will be prompted to overwrite files, indicates [A]ll and let it go.

    Image 3

Basic Authentication Ready

Something great about this sample project is everything is ready to deploy a very basic version of a website with authentication integrated. It needs few tweaks to make it work even with Google, Facebook or Twitter, but I prefer to go through the most interesting part in another article, signing-in with Google and going back to the website in order to just capture an email is not exciting neither very useful.

Run the website, it takes you to the default template website which works perfectly, you can try to register a new account to see everything is working correctly. This installation creates a local database and hooks up to it, creating tables and basic data. The most interesting part is just about to start, in my opinion this basic website is ok but it's useless, it contains a lot of code that no one can seriously use like destroying/recreating the database every time something changes (I bet you don't want that). It's also a basic template that needs for sure to be extended (users contain few fields). Roles management is not very well thought in my opinion, it's too basic and it doesn't make too much sense to extend it due to the way it's used (hard-coded in the controller using decorators most of the time).

Image 4

StartUp

Most of the magic starts in the new ConfigureAuth method code, if 1.0 was very simple and non-extensible, now you can see it's completely rewritten and relies on OWin for everything.

C#
public void ConfigureAuth(IAppBuilder app)
        {
            // Configure the db context, user manager and role manager 
            // to use a single instance per request
            app.CreatePerOwinContext(ApplicationDbContext.Create);
            app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
            app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);
            app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);

            // Enable the application to use a cookie to store information for the signed in user
            // and to use a cookie to temporarily store information 
            // about a user logging in with a third party login provider
            // Configure the sign in cookie
            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                LoginPath = new PathString("/Account/Login"),
                Provider = new CookieAuthenticationProvider
                {
                    // Enables the application to validate the security stamp when the user logs in.
                    // This is a security feature which is used 
                    // when you change a password or add an external login to your account.  
                    OnValidateIdentity = SecurityStampValidator.OnValidateIdentity
                        <ApplicationUserManager, ApplicationUser>(
                        validateInterval: TimeSpan.FromMinutes(30),
                        regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
                }
            });
            app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

            // Enables the application to temporarily store user information 
            // when they are verifying the second factor in the two-factor authentication process.
            app.UseTwoFactorSignInCookie(DefaultAuthenticationTypes.TwoFactorCookie, 
                     TimeSpan.FromMinutes(5));

            // Enables the application to remember the second login verification factor 
            // such as phone or email.
            // Once you check this option, your second step of verification during the login 
            // process will be remembered on the device where you logged in from.
            // This is similar to the RememberMe option when you log in.
            app.UseTwoFactorRememberBrowserCookie
               (DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie);

            // Uncomment the following lines to enable logging in with third party login providers
            //app.UseMicrosoftAccountAuthentication(
            //    clientId: "",
            //    clientSecret: "");

            //app.UseTwitterAuthentication(
            //   consumerKey: "",
            //   consumerSecret: "");

            //app.UseFacebookAuthentication(
            //   appId: "",
            //   appSecret: "");

            //app.UseGoogleAuthentication(
            //    clientId: "",
            //    clientSecret: "");
        }

I've seen people that don't like to rely on OWin and rewrote a lot of code to decouple it. It makes sense if you want to even be able to test the authorization process but I didn't need it and I let it untouched. I understand it violates some principles of decoupling and single responsibility but I better make it simpler at least for now.

We can pay attention to the external sign-in's integrated here, not very different to the ones before but the real power is going to be described later (it's possible to go way further now).

If you have an application set in Facebook, Gmail or Twitter, just uncomment the code above and enter your keys, it magically works and you will see every login set on the right side of the login webpage.

Image 5

I insist on the fact it's not very useful yet, it works and it solves us tons of code we used to create just to login into an application and register users. This default website also allows us to manage users and roles. I don't want to go through these features because they're not so important. In the next article, I will describe how to extend users, modify the default database patterns context and modify some features that are normally very useful (table names for example).

Points of Interest

If you want to read something very interesting, I suggest you to go through this great article I found when I was looking for information related to this topic.

It's about bearer tokens, it makes a lot of sense and it's explained very well, you should check it!

Next Article

Continue reading this topic in the following article:

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here