Step 2. Adding a Model with User Credentials

Step 2. Adding a Model with User Credentials

Skip and go to the next step

In order to keep implementation of the login system separately from the rest of application, we'll define it in a separate class-library project within the same solution. We will build our membership system using ASP.NET Identity.

The following illustration shows the folder structure of the project:

 task manager project structure

Step 2.1. Creating a Project

Your actions:

  1. Select SolutionAddNew Project → Your language → WindowsClass Library
  2. In the Name box, enter Scheduler.MVC5.Users
  3. In the Location box, enter a name for the project folder
  4. Select Create directory for solution
  5. Click Ok

Step 2.2. Adding Core Libraries

Add references to the library via Nuget (Package Manager Console).

Note: Please, check your Default Project in all installations of the Nuget packages:

 core libraries

PM>Install-Package EntityFramework
PM>Install-Package Microsoft.AspNet.Identity.Core
PM>Install-Package Microsoft.AspNet.Identity.EntityFramework
PM>Install-Package Microsoft.AspNet.Identity.Owin
PM>Install-Package Microsoft.Owin.Host.SystemWeb -Version 2.1.0

Add following references: System.Web

Step 2.3. Updating App.Config

Add connectionStrings to the app.config file:

 <configuration>
<connectionStrings>
    <add name="TaskManagerString" connectionString="data source=(LocalDB)\v11.0;attachdbfilename=|DataDirectory|\TaskManager.mdf;integrated security=True;connect timeout=30;MultipleActiveResultSets=True;App=EntityFramework" providerName="System.Data.SqlClient" />
  </connectionStrings>
</configuration>

Step 2.4. Implementing the Basics Classes

  • ApplicationUser

ApplicationUser class represents a user entry of the application. It should be inherited from the IdentityUser class, that is the default user implementation of EntityFramework.

UserIdentityDbContext represents a class that uses the default entity types for ASP.NET Identity Users, Roles, Claims, Logins.

  1. Create a folder UserStore in the project
  2. Select UserStore,right click AddNew Item → Your language → CodeClass
  3. Enter ApplicationUser in the *Name* box
  4. Click Ok

Update the code as follows:

using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
 
namespace Scheduler.MVC5.Users
{
    /// <summary>
    ///  represents default EntityFramework IUser implementation
    /// </summary>
    public class ApplicationUser : IdentityUser
    {
        public async Task<ClaimsIdentity> GenerateUserIdentityAsync(AppUserManager manager)
        {
            return await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        }
    }
    /// <summary>
    /// represents a class that uses the default entity types for ASP.NET Identity Users, Roles, Claims, Logins
    /// </summary>
    public class UserIdentityDbContext : IdentityDbContext<ApplicationUser>
    {
        public UserIdentityDbContext()
            : base("TaskManagerString")
        {
        }
 
        public UserIdentityDbContext Create()
        {
            return new UserIdentityDbContext();
        }
 
        protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.Entity<ApplicationUser>().ToTable("Users");
            modelBuilder.Entity<IdentityRole>().ToTable("Roles");
            modelBuilder.Entity<IdentityUserRole>().ToTable("UserInRoles");
 
        }
    }   
}

Note: TaskManagerString is the name of the connection string for the task manager database. It is contained in the app.config

  • AppUserManager

Exposes user related APIs, which will automatically save changes to the UserStore.

  1. Add a New Item to the project with the Name UserManager
  2. Update the code as follows:
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin;
 
namespace Scheduler.MVC5.Users
{
    /// <summary>
    /// Exposes user related APIs which will automatically save changes to the UserStore
    /// </summary>
    public class AppUserManager : UserManager<ApplicationUser>
    {
        public AppUserManager(IUserStore<ApplicationUser> store) : base(store)
        {
        }
        public AppUserManager Create(IdentityFactoryOptions<AppUserManager> options, IOwinContext context)
        {
            var manager =
                new AppUserManager(new UserStore<ApplicationUser>(context.Get<UserIdentityDbContext>()));
 
            return manager;
        }
    }
}
  • UserIdentityDbContext

UserIdentityDbContext class will delete, recreate, and optionally re-seed the database only if the model has changed since the database was created.

1. Select UserSrore and right click AddNew Item→ Your language → CodeClass

2. Enter UserIdentityDbContext in the Name box

3. Click Ok

4. Update the code as follows:

using System.Data.Entity;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
 
namespace Scheduler.MVC5.Users
{
    public class UserIdentityDbContextInit : CreateDatabaseIfNotExists<UserIdentityDbContext>
    {}
}

5. If you need some default data in the database, you need to override the method Seed. The default implementation does nothing. We'll update it in order to create the default users an roles:

using System.Data.Entity;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
 
namespace Scheduler.MVC5.Users
{
    public class UserIdentityDbContextInit : CreateDatabaseIfNotExists<UserIdentityDbContext>
    {
        protected override void Seed(UserIdentityDbContext context)
        {
            InitTables(context);
            base.Seed(context);
        }
 
        private void InitTables(UserIdentityDbContext context)
        {
            var userManager = new AppUserManager(new UserStore<ApplicationUser>(context));
            var rolemanager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(context));
            var names = new[]{"Manager","David","Dana","Linda","John"};
            var roles = new[]{"Manager", "Employee"};
 
            //Create role(s) if not exists
 
            foreach (var role in roles)
            {
                if (!rolemanager.RoleExists(role))
                {
                    rolemanager.Create(new IdentityRole(role));
                } 
            }
 
            //Create user(s)
 
            foreach (var name in names)
            {
                var user = new ApplicationUser()
                {
                    UserName = name
                };
                var result = userManager.Create(user, "password");
 
                //and adding user role(s)
 
                if (result.Succeeded)
                {
                    string role = name == "Manager" ? "Manager" : "Employee";
                    userManager.AddToRole(user.Id, role);
                }
            }
        }
    }
}
  • SignInHelper

This class will handle login/logout user attempts.

  1. Add a New Item to the project with the Name SignInHelper
  2. Update the code as follows:
using System.Threading.Tasks;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin.Security;
 
namespace Scheduler.MVC5.Users
{
   public class SignInHelper
    {
        public AppUserManager AppUserManager { get; private set; }
        public IAuthenticationManager AuthenticationManager { get; set; }
 
        public SignInHelper(AppUserManager userManager, IAuthenticationManager authManager)
        {
            this.AppUserManager = userManager;
            this.AuthenticationManager = authManager;
        }
 
 
        public async Task SignInAsync(ApplicationUser user, bool isPersistent, bool rememderBrowser)
        {
            AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie,
                DefaultAuthenticationTypes.TwoFactorCookie);
            var userIdentity = await user.GenerateUserIdentityAsync(AppUserManager);
            if (rememderBrowser)
            {
                var rememberBrowserIdentity = AuthenticationManager.CreateTwoFactorRememberBrowserIdentity(user.Id);
                AuthenticationManager.SignIn(new AuthenticationProperties() {IsPersistent = isPersistent}, userIdentity,
                    rememberBrowserIdentity);
            }
            else
            {
                AuthenticationManager.SignIn(new AuthenticationProperties(){IsPersistent = isPersistent},userIdentity);
            }
        }
 
        public async Task<string> PasswordSignIn(string userName, string password, bool isPersistent)
        {
           var user = await AppUserManager.FindByNameAsync(userName);
            if (user == null)
            {
                return SignInStatus.Failure.ToString();
            }
            if (await AppUserManager.CheckPasswordAsync(user, password))
            {
                await SignInAsync(user, isPersistent, false);
                return SignInStatus.Success.ToString();
            }
            if (await AppUserManager.IsLockedOutAsync(user.Id))
            {
                return SignInStatus.LockedOut.ToString();
            }
            return SignInStatus.Failure.ToString();
        }
 
    }
}
  • AppUserManagerProvider
  1. Add project a new class named AppUserManagerProvider to the Scheduler.MVC5.Users
  2. Update the code as follows:
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin.Security;
 
namespace Scheduler.MVC5.Users
{
    public class AppUserManagerProvider
    {
       UserIdentityDbContext _dbUsers = new UserIdentityDbContext();
 
        UserIdentityDbContext Db
        {
            get
            {
                if (_dbUsers == null)
                    _dbUsers=new UserIdentityDbContext();
                return _dbUsers;
            }
        }
 
        private static AppUserManager _userManager;
        public static AppUserManager GetAppUserManager
        {
            get
            {
                return _userManager ??
                       (_userManager = HttpContext.Current.GetOwinContext().GetUserManager<AppUserManager>());
            }
            set
            {
                if (value != null)
                {
                    _userManager = value;
                }
            }
        }
 
        public List<ApplicationUser> Users
        {
            get { return Db.Users.ToList(); }
        }
 
        public string UserId { get { return HttpContext.Current.User.Identity.GetUserId(); } }
 
        public List<string> GetUserRolesName(string id)
        {
            return Db.Roles.Select(o=>o.Name).ToList();
        }
 
        public static IAuthenticationManager AuthenticationManager
        {
            get
            {
                return HttpContext.Current.GetOwinContext().Authentication;
            }
        }
    }
}

At the end Build Library and Add Reference to TaskManager.MVC5 site.



 previous button step two next button


comments powered by Disqus