dotnetIntelligency

Monday, January 30, 2017

HOW TO: CREATE ASP.NET MVC AUTHENTICATION TABLES IN AN EXISTING DATABASE
Background
When you create a MVC web application in VS 2013, VS embed a sql server database in your project, and this project is being used as a source of asp.net membership. Since you will not use this database as an embedded file and you want to have it as part of your existing database in SQL Server instance. The file is created under App_Data folder. To see the .mdf file click on Show all files in the solution explorer.
You can see the contents of this database and all tables in the server explorer window.
How to create those tables in SQL server ?
First, you can delete the .mdf file in App_Data folder. Since we don’t need any of these tables.Then, we need to update the default connection string in the web.config to point to our database.
<connectionStrings>
    <add name=”DefaultConnection” connectionString=”Data Source=SERVER\INSTANCENAME;Initial Catalog=DBNAME;Integrated Security=True” providerName=”System.Data.SqlClient” />
  </connectionStrings>
Third, Open Nuget Package Manager and write the following commands:
Enable-Migrations
Add-Migration Init
Update-Database
Check out your database, all ASP.NET membership tables with Prefix Asp have been create and then you can test it out by running your application and execute membership actions such as Signing up or Signing in to your application.
Created tables after running above commands:
AspNetRoles
AspNetUserClaims
AspNetUserLogins
AspNetUserRoles
AspNetUsers
__MigrationHistory

Sunday, January 15, 2017

Creating a custom Authentication Filter

AuthenticationFilter has been introduced newly in ASP.NET MVC 5+ to provide fine-grain control over how users are authenticated for controllers and action methods. 

Creating a custom Authentication Filter

Problem Scenario

Assume a scenario, where we want our Controller or an action methods available only to user having role as Admin or SuperAdmin.

Normally, we would write following attribute to the controller

    [Authorize(Roles = "Admin, SuperAdmin")]
    public class AdminSuperAdminController : Controller
    {   

    }

Tuesday, January 3, 2017

The Dependency Injection Life cycle: Register, Resolve, Dispose

The Unity container can manage this register, resolve, dispose cycle making it easy to use dependency injection in your applications.

Typically, you perform the registration of the types that require dependency injection in a single method in your application; you should invoke this method early in your application’s life-cycle to ensure that the application is aware of all of the dependencies between its classes. Unity also supports configuring the container declaratively from a configuration file.

You should always try to write container-agnostic code (except for the one place at the root of the application where you configure the container) in order to decouple your application from the specific dependency injection container you are using.

Register

Using the Unity container, you can register a set of mappings that determine what concrete type you require when a constructor (or property or method) identifies the type to be injected by an interface type or base class type. As a reminder, here is a copy of the constructor in the ManagementController class showing that it requires an injection of an object that implements the ITenantStore interface.
public ManagementController(ITenantStore tenantStore)
{
    this.tenantStore = tenantStore;
}
The following code sample shows how you could create a new Unity container and then register the concrete type to use when a ManagementController instance requires an ITenantStore instance.
var container = new UnityContainer();
container.RegisterType<ITenantStore, TenantStore>();

The RegisterType method shown here tells the container to instantiate a TenantStore object when it instantiates an object that requires an injection of an ITenantStore instance through a constructor, or method, or property. This example represents one of the simplest types of mapping that you can define using the Unity container.

Resolve

The usage of the RegisterType method shown in the previous section defines the mapping between the interface type used in the client class and the concrete type that you want to use in the application. To instantiate the ManagementController and TenantStore objects, you must invoke the Resolve method.
var controller = container.Resolve<ManagementController>();

Note that in this example, you do not instantiate the ManagementController object directly, rather you ask the Unity container to do it for you so that the container can resolve any dependencies. In this simple example, the dependency to resolve is for an ITenantStore object. Behind the scenes, the Unity container first constructs a TenantStore object and then passes it to the constructor of the ManagementController class.

Dispose

In the simple example shown in the previous two sections on registering and resolving types, the application stores a reference to the Management-
Controller object in the controller variable and the Unity container creates a new TenantStore instance to inject whenever you call the Resolve method. When the controller variable goes out of scope and becomes eligible for garbage collection, the TenantStore object will also be eligible for garbage collection.

Sunday, January 1, 2017

default Role and Admin User

Create default Role and Admin User
Firstly, create default user role like “Admin”,”Manager”, etc and also we will create a default admin user. We will be creating all default roles and user in “Startup.cs”

OWIN (OPEN WEB Interface for .NET) defines a standard interface between .NET and WEB Server and each OWIN application has a Startup Class where we can specify components.
In “Startup.cs” file we can find the Configuration method. From this method we will be calling our createRolesandUsers() method to create a default user role and user. We will check for Roles already created or not. If Roles, like Admin, is not created, then we will create a new Role as “Admin” and we will create a default user and set the user role as Admin. We will be using this user as super user where the user can create new roles from our MVC application. 
public void Configuration(IAppBuilder app)   
{   
 ConfigureAuth(app);   
 createRolesandUsers();   
}   
   
// In this method we will create default User roles and Admin user for login   
private void createRolesandUsers()   
{   
 ApplicationDbContext context = new ApplicationDbContext();   
 var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(context));   
 var UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));   
   
 // In Startup iam creating first Admin Role and creating a default Admin User    
 if (!roleManager.RoleExists("Admin"))   
 {   
  // first we create Admin rool   
  var role = new Microsoft.AspNet.Identity.EntityFramework.IdentityRole();   
  role.Name = "Admin";   
  roleManager.Create(role);   
   
 //Here we create a Admin super user who will maintain the website                  
  var user = new ApplicationUser();   
  user.UserName = "shanu";   
  user.Email = "syedshanumcain@gmail.com";   
   
  string userPWD = "A@Z200711";   
  var chkUser = UserManager.Create(user, userPWD);   
  //Add default User to Role Admin   
  if (chkUser.Succeeded)   
  {   
   var result1 = UserManager.AddToRole(user.Id, "Admin");   
  }   
 }   
// creating Creating Manager role    
if (!roleManager.RoleExists("Manager"))   
{   
 var role = new Microsoft.AspNet.Identity.EntityFramework.IdentityRole();   
  role.Name = "Manager";   
  roleManager.Create(role);   
}   
// creating Creating Employee role    
if (!roleManager.RoleExists("Employee"))   
{   
  var role = new Microsoft.AspNet.Identity.EntityFramework.IdentityRole();   
  role.Name = "Employee";   
  roleManager.Create(role);   
 }   
When we run our application we can see new default ASP.NET user related tables will be created in our AttendanceDB Database. Here we can see in the following image as all ASP.NET user related tables will be automatically created when we run our application and also all our default user roles will be inserted in AspNetRoles table and default admin user will be created in AspNetUsers table.

By default for user registration in ASP.NET MVC 5 we can use Email and passoword. Here, we will customize the default user registration with adding a username and a ComboBox to display the user roles. User can enter their username and select there user role during registration.
View Part: Firstly, add a TextBox for username and ComboBox for displaying User Role in Register.cshtml,


Double click the Register.cshtml and change the html code like the following to add textbox and combobox with caption. Here we can see first we add a textbox and Combobox .We bind the combobox with (SelectList) ViewBag.Name. 

HTML
@model shanuMVCUserRoles.Models.RegisterViewModel   
@{   
    ViewBag.Title = "Register";   
}   
   
<h2>@ViewBag.Title.</h2>   
   
@using (Html.BeginForm("Register", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))   
{   
    @Html.AntiForgeryToken()   
    <h4>Create a new account.</h4>   
    <hr />   
    @Html.ValidationSummary("", new { @class = "text-danger" })   
    <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>   
   
   
    <div class="form-group"  
        @Html.LabelFor(m => m.UserName, new { @class = "col-md-2 control-label" })   
        <div class="col-md-10"  
            @Html.TextBoxFor(m => m.UserName, new { @class = "form-control" })   
        </div>   
    </div>   
    <div class="form-group"  
        @Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" })   
        <div class="col-md-10"  
            @Html.PasswordFor(m => m.Password, new { @class = "form-control" })   
        </div>   
    </div>   
    <div class="form-group"  
        @Html.LabelFor(m => m.ConfirmPassword, new { @class = "col-md-2 control-label" })   
        <div class="col-md-10"  
            @Html.PasswordFor(m => m.ConfirmPassword, new { @class = "form-control" })   
        </div>   
    </div>   
   
    <div class="form-group"  
        @Html.Label("user Role", new { @class = "col-md-2 control-label" })   
        <div class="col-md-10"  
            @*@Html.DropDownList("Name")*@   
            @Html.DropDownList("UserRoles", (SelectList)ViewBag.Name, " ")   
        </div>   
    </div>   
   
    <div class="form-group"  
        <div class="col-md-offset-2 col-md-10"  
            <input type="submit" class="btn btn-default" value="Register" />   
        </div>   
    </div>   
}   
   
@section Scripts {   
    @Scripts.Render("~/bundles/jqueryval")   
}  
 Model Part

Next in 
AccountViewModel.cs check for the RegisterViewModel and add the UserRoles and UserName properties with required for validation.
Double click the AccountViewModel.cs file from Models folder, find the RegisterViewModel class, add UserName and UserRoles properties as in the following. 

C#
public class RegisterViewModel   
    {   
        [Required]   
        [Display(Name = "UserRoles")]   
        public string UserRoles { getset; }   
   
        [Required]   
        [EmailAddress]   
        [Display(Name = "Email")]   
        public string Email { getset; }   
   
        [Required]   
        [Display(Name = "UserName")]   
        public string UserName { getset; }   
   
        [Required]   
        [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]   
        [DataType(DataType.Password)]   
        [Display(Name = "Password")]   
        public string Password { getset; }   
   
        [DataType(DataType.Password)]   
        [Display(Name = "Confirm password")]   
        [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]   
        public string ConfirmPassword { getset; }   
    }  
Controller Part

Next in
 AccountController.cs first we get all the role names to be bound in ComboBox except Admin role and in register button click we will add the functionality to insert username and set user selected role in ASP.NET identity database.

Firstly, create an object for our ApplicationDBContext. Here, ApplicationDBContext is a class which is used to perform all ASP.NET Identity database functions like create user, roles, etc. 
C#
ApplicationDbContext context;   
        public AccountController()   
        {   
            context = new ApplicationDbContext();   
        }  





Register ActionResult method: 
Using the ApplicationDBConterxt object we will get all the roles from database. For user registration we will not display the Admin roles. User can select rest of any role type during registration. 
C#
// GET: /Account/Register   
        [AllowAnonymous]   
        public ActionResult Register()   
        {   
            ViewBag.Name = new SelectList(context.Roles.Where(u => !u.Name.
               Contains("Admin")).ToList(), "Name""Name");   
            return View();   
        }  
 Register User

By default the user email will be stored as username in AspNetUsers table. Here we will change to store the user entered name. After user was created successfully we will set the user selected role for the user.
C#
// POST: /Account/Register   
        [HttpPost]   
        [AllowAnonymous]   
        [ValidateAntiForgeryToken]   
        public async Task<ActionResult> Register(RegisterViewModel model)   
        {   
            if (ModelState.IsValid)   
            {   
var user = new ApplicationUser { UserName = model.UserName, Email = model.Email };           var result = await UserManager.CreateAsync(user, model.Password);   
if (result.Succeeded)   
{   
await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);      
// For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=320771   
 // Send an email with this link   
// string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);   
// var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);   
//await UserManager.SendEmailAsync(user.Id, "Confirm your account", "Please confirm your account by clicking <a href=\"" + callbackUrl + "\">here</a>");   
//Assign Role to user Here      
                   await this.UserManager.AddToRoleAsync(user.Id, model.UserRoles);
                    //Ends Here    
                    return RedirectToAction("Index""Users");   
}   
ViewBag.Name = new SelectList(context.Roles.Where(u => !u.Name.Contains("Admin")).
ToList(), "Name""Name");   
                AddErrors(result);   
            }   
               // If we got this far, something failed, redisplay form   
            return View(model);   
        }  

Customize User login
In the same way as user registration we will customize user login to change email as username to enter. By default in ASP.NET MVC 5 for login user needs to enter Email and password. Here we will customize for user by entering username and password. In this demo we are not using any other Facebook, Gmail or Twitter login so we will be using UserName instead of Email.
View Part

Here we will change the email with UserName in 
Login.cshtml. We can find the Login.cshtml file from the folder inside Views/Account/Login.cshtml.
C#
@using shanuMVCUserRoles.Models   
@model LoginViewModel   
@{   
    ViewBag.Title = "Log in";   
}   
   
<h2>@ViewBag.Title</h2>   
<div class="row">   
    <div class="col-md-8">   
        <section id="loginForm">   
            @using (Html.BeginForm("Login""Account"new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { @class = "form-horizontal", role = "form" }))   
            {   
                @Html.AntiForgeryToken()   
                <h4>Use a local account to log in.</h4>   
                <hr />   
                @Html.ValidationSummary(true""new { @class = "text-danger" })   
                <div class="form-group">   
                    @Html.LabelFor(m => m.UserName, new { @class = "col-md-2 control-label" })   
                    <div class="col-md-10">   
                        @Html.TextBoxFor(m => m.UserName, new { @class = "form-control" })   
                        @Html.ValidationMessageFor(m => m.UserName, ""new { @class = "text-danger" })   
                    </div>   
                </div>   
                <div class="form-group">   
                    @Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" })   
                    <div class="col-md-10">   
                        @Html.PasswordFor(m => m.Password, new { @class = "form-control" })   
                        @Html.ValidationMessageFor(m => m.Password, ""new { @class = "text-danger" })   
                    </div>   
                </div>   
                <div class="form-group">   
                    <div class="col-md-offset-2 col-md-10">   
                        <div class="checkbox">   
                            @Html.CheckBoxFor(m => m.RememberMe)   
                            @Html.LabelFor(m => m.RememberMe)   
                        </div>   
                    </div>   
                </div>   
                <div class="form-group">   
                    <div class="col-md-offset-2 col-md-10">   
                        <input type="submit" value="Log in" class="btn btn-default" />   
                    </div>   
                </div>   
                <p>   
                    @Html.ActionLink("Register as a new user""Register")   
                </p>   
                @* Enable this once you have account confirmation enabled for password reset functionality   
                    <p>   
                        @Html.ActionLink("Forgot your password?""ForgotPassword")   
                    </p>*@   
}   
        </section>   
    </div>   
    <div class="col-md-4">   
        <section id="socialLoginForm">   
            @Html.Partial("_ExternalLoginsListPartial"new ExternalLoginListViewModel { ReturnUrl = ViewBag.ReturnUrl })   
        </section>   
    </div>   
</div>   
   
@section Scripts {   
    @Scripts.Render("~/bundles/jqueryval")   
}  
 Model Part

Same as Registration in AccountViewModel we need to find the loginViewModel to change the Email with UserName,


Here in the following code we can see that we have changed the Email property to UserName.  
C#
public class LoginViewModel   
    {   
        [Required]   
        [Display(Name = "UserName")]   
   
        public string UserName { getset; }   
   
        [Required]   
        [DataType(DataType.Password)]   
        [Display(Name = "Password")]   
        public string Password { getset; }   
   
        [Display(Name = "Remember me?")]   
        public bool RememberMe { getset; }   
    }  
Controller Part:

In login button click we need to change the email with username to check from database for user Authentication. Here in the following code we can see as we changed the email with username after successful login we will be redirect to the user page. Next we will see how to create a user page and display the text and menu by user role. 
C#
// POST: /Account/Login   
        [HttpPost]   
        [AllowAnonymous]   
        [ValidateAntiForgeryToken]   
        public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)   
        {   
            if (!ModelState.IsValid)   
            {   
                return View(model);   
            }   
   
            // This doesn't count login failures towards account lockout   
            // To enable password failures to trigger account lockout, change to shouldLockout: true   
            var result = await SignInManager.PasswordSignInAsync(model.UserName, model.Password, model.RememberMe, shouldLockout: false);   
            switch (result)   
            {   
                case SignInStatus.Success:   
                    return RedirectToLocal(returnUrl);   
                case SignInStatus.LockedOut:   
                    return View("Lockout");   
                case SignInStatus.RequiresVerification:   
                    return RedirectToAction("SendCode"new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });   
                case SignInStatus.Failure:   
                default:   
                    ModelState.AddModelError("""Invalid login attempt.");   
                    return View(model);   
            }   
        }   
   
        //   
        // GET: /Account/VerifyCode   
        [AllowAnonymous]   
        public async Task<ActionResult> VerifyCode(string provider, string returnUrl, bool rememberMe)   
        {   
            // Require that the user has already logged in via username/password or external login   
            if (!await SignInManager.HasBeenVerifiedAsync())   
            {   
                return View("Error");   
            }   
            return View(new VerifyCodeViewModel { Provider = provider, ReturnUrl = returnUrl, RememberMe = rememberMe });   
        }  
Authenticated and Authorized User page
Here we create a new page for displaying message of Authenticated and Authorized user by their role.
If the logged in user role is Admin, then we will display the welcome message for Admin and display the menu forcreating new roles.
If the logged in users roles are Manager, Employee, Accounts, etc. then we will display a welcome message for them.
Firstly, create a new Empty Controller named “userscontroller.cs”. In this controller first we add the [Authorize] at the top of controller for checking the valid users.
Creating our View: Right click on index ActionResult and create a view .
In view we check for the ViewBag.displayMenu value. If the value is “Yes", then we display the Admin welcome message and a link for creating new Menu. If the ViewBag.displayMenu is “No, then display other users name with welcome message. 
HTML
@{   
    ViewBag.Title = "Index";   
}   
   
   
   
@if (ViewBag.displayMenu == "Yes")   
{   
    <h1>Welcome Admin. Now you can create user Role.</h1>   
    <h3>   
        <li>@Html.ActionLink("Manage Role", "Index", "Role")</li>   
    </h3>   
}   
else   
{   
    <h2>  Welcome <strong>@ViewBag.Name</strong> :) .We will add user module soon </h2>   
}  
Controller part
In controller we will check the user is logged in to the system or not. If the user did not log in, then
Display the message as “Not Logged In” and if the user is authenticated, then we check the logged in users role. If the users role is “Admin", then we set ViewBag.displayMenu = "Yes", else we setViewBag.displayMenu = "No"
C#
public ActionResult Index()   
        {   
            if (User.Identity.IsAuthenticated)   
            {   
                var user = User.Identity;   
                ViewBag.Name = user.Name;   
               
                ViewBag.displayMenu = "No";   
   
                if (isAdminUser())   
                {   
                    ViewBag.displayMenu = "Yes";   
                }   
                return View();   
            }   
            else   
            {   
                ViewBag.Name = "Not Logged IN";   
            }   
            return View();   
   
        }  
For checking the user is logged in we create method and return the Boolean value to our main Index method. 
C#
public Boolean isAdminUser()   
        {   
            if (User.Identity.IsAuthenticated)   
            {   
                var user = User.Identity;   
                ApplicationDbContext context = new ApplicationDbContext();   
                var UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));   
                var s = UserManager.GetRoles(user.GetUserId());   
                if (s[0].ToString() == "Admin")   
                {   
                    return true;   
                }   
                else   
                {   
                    return false;   
                }   
            }   
            return false;   
        }  
Admin users can create Roles
We already saw that if the Admin user is logged in then we will display the link for creating new users. For admin login we have already created a default user with UserName as "shanu" and password as "A@Z200711",
For creating user role by admin first we will add a new empty controller and named it RoleController.cs,
In this controller we check that the user role is Admin. If the logged in user role is Admin, then we will get all the role names using ApplicationDbContext object. 
C#
public ActionResult Index()   
        {   
   
            if (User.Identity.IsAuthenticated)   
            {   
   
   
                if (!isAdminUser())   
                {   
                    return RedirectToAction("Index""Home");   
                }   
            }   
            else   
            {   
                return RedirectToAction("Index""Home");   
            }   
   
            var Roles = context.Roles.ToList();   
            return View(Roles);   
   
        }  
 In view we bind all the user roles inside html table. 
HTML
@model IEnumerable<Microsoft.AspNet.Identity.EntityFramework.IdentityRole  
@{   
    ViewBag.Title = "Add Role";   
}   
<table style=" background-color:#FFFFFF; border: dashed 3px #6D7B8D; padding: 5px;width: 99%;table-layout:fixed;" cellpadding="6" cellspacing="6"  
    <tr style="height: 30px; background-color:#336699 ; color:#FFFFFF ;border: solid 1px #659EC7;"  
        <td align="center" colspan="2"  
            <h2> Create User Roles</h2>   
        </td>   
   
    </tr>   
   
    <tr>   
        <td>   
            <table id="tbrole" style="width:100%; border:dotted 1px; background-color:gainsboro; padding-left:10px;"  
   
                @foreach (var item in Model)   
                {   
                    <tr>   
                        <td style="width:100%; border:dotted 1px;"  
                            @item.Name   
                        </td>   
                    </tr>}   
            </table>   
        </td>   
        <td align="right" style="color:#FFFFFF;padding-right:10;"  
   
   
            <h3>   @Html.ActionLink("Click to Create New Role", "Create", "Role") </h3>   
        </td>   
    </tr>   
</table> 
More Information
Firstly, create a sample AttendanceDB Database in your SQL Server. In the Web.Config file change the DefaultConnection connection string with your SQL Server Connections. In Startup.cs file I have created default Admin user with UserName "shanu" and password "A@Z200711." This UserName and password will be used to login as Admin user. You can change this user name and password as you like. For security reason after log in as Admin you can change the Admin user password as you like,