Customizing ASP.NET Identity in MVC 5

For those of you that follow my Blog you know that one of the subjects I write a lot about is customizing SimpleMembership for ASP.NET security in web applications and some of you have been asking if I have tried using it with Visual Studio 2013 RC or Preview.  Recently I have taken the time to explore using SimpleSecurity and SimpleMembership with VS 2013 RC and more recently the final release now available to MSDN Subscribers.   The short of it is there are problems with upgrading to MVC 5,  which was released to coincide with VS 2013, as described in this StackOverflow QA.  You can still develop your MVC 4 applications in VS 2013 but you will miss out on some of the new features available in MVC 5 and Razor 3.

The other problem is that SimpleMembership is going away in MVC 5 as the provider for ASP.NET security.  Microsoft has gone to another membership provider called ASP.NET Identity. In this article I will start looking at how to customize ASP.NET Identity and contrast that with using SimpleMembership.  There are a number of new features and benefits in ASP.NET Identity that you can read about here.  The benefits and the fact that this is the chosen direction for ASP.NET security make a compelling reason to look into using this going forward.

It turns out that it is quite simple to customize the user profile in ASP.NET Identity.  First I started by creating a new MVC 5 application.  You no longer select whether you want an Internet or Intranet application, you just select the MVC template and select the authentication type you want to use. For an Internet type application you select Individual User Accounts.  Once your web application is created open IdentityModels.cs in the Models directory.  You will see a class called ApplicationUser which is analogues to the UserProfile in SimpleMembership.  It is an empty class that inherits from IdentityUser which has these properties.

    public class IdentityUser : IUser
    {
        public IdentityUser();
        public IdentityUser(string userName);

        public virtual ICollection<identityuserclaim> Claims { get; }
        public virtual string Id { get; set; }
        public virtual ICollection<identityuserlogin> Logins { get; }
        public virtual string PasswordHash { get; set; }
        public virtual ICollection<identityuserrole> Roles { get; }
        public virtual string SecurityStamp { get; set; }
        public virtual string UserName { get; set; }
    }

What you will notice from this implementation is that the Id is no longer an integer as it was SimpleMembership. It now uses a string which the default implementation stuffs with a GUID. In this example I will just add an email address to the user so we can look at adding email confirmation in a later article. Here is what it looks like.

    public class ApplicationUser : IdentityUser
    {
        public string Email { get; set; }
    }

Now to allow the user to enter their email address during registration I first update the registration model.

    public class RegisterViewModel
    {
        [Required]
        [Display(Name = "User name")]
        public string UserName { get; set; }

        [Required]
        [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
        [DataType(DataType.Password)]
        [Display(Name = "Password")]
        public string Password { get; set; }

        [DataType(DataType.Password)]
        [Display(Name = "Confirm password")]
        [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
        public string ConfirmPassword { get; set; }

        [Required]
        [Display(Name = "Email address")]
        public string Email { get; set; }

    }

And then I update the View to include a label and text box for the email.

   <div class="form-group">
        @Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.TextBoxFor(m => m.Email, new { @class = "form-control" })
        </div>
    </div>

To test this out I changed the About page to display the current users email. This also shows how we can access user information in the application.

    public ActionResult About()
    {
        ViewBag.Message = "Your application description page.";
        UserManager<ApplicationUser> UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));         
        var user = UserManager.FindById(User.Identity.GetUserId());
        if (user != null)
            ViewBag.Email = user.Email;
        else
            ViewBag.Email = "User not found.";

        return View();
    }

That is all there is to customizing the user information you can store when using ASP.NET Identity.  In a future article I will look at how we can add email confirmation to ASP.NET Identity.

Also follow this Blog for future updates as I continue to investigate if you can upgrade an existing MVC 4 application with SimpleMembership to MVC 5. It would be nice to migrate an existing application to MVC 5 without throwing away your whole security model and database.

Comments

Popular posts from this blog

Using Claims in ASP.NET Identity

Seeding & Customizing ASP.NET MVC SimpleMembership

Customizing Claims for Authorization in ASP.NET Core 2.0