Role Based Authentication In ASP.NET MVC

Introduction

 
This article will explain the role-based authentication in ASP.NET MVC, with examples. I strongly recommended reading my previous articles before proceeding to this article as it is a continuation part of my previous article. 
Step 1
 
Open your favourite SQL Server database with any version. It really doesn’t matter what version it is. Create the following database data tables. 
  1. create table Employee  
  2. (  
  3.    EmpId int primary key identity (1,1),  
  4.    Name nvarchar(50),  
  5.    Gender char(10),  
  6.    Age int,  
  7.    Position nvarchar(50),  
  8.    Office nvarchar(50),  
  9.    HireDate datetime,  
  10.    Salary int,  
  11.    DepartmentId int  
  12. )  
  13.   
  14. create table Department  
  15. (  
  16.    DeptId int primary key identity(1,1),  
  17.    DepartmentName nvarchar(50)  
  18. )  
  19.   
  20. create table Users  
  21. (  
  22.    Id int primary key identity(1,1),  
  23.    Username nvarchar(50),  
  24.    Password nvarchar(50)  
  25. )  
  26.   
  27. create table Roles  
  28. (  
  29.    Id int primary key identity(1,1),  
  30.    RoleName nvarchar(50)  
  31. )  
  32.   
  33. create table UserRoleMapping  
  34. (  
  35.    Id int primary key identity(1,1),  
  36.    UserId int,  
  37.    RoleId int  
  38. )  
  39.   
  40. alter table Employee Add foreign key  
  41. (DepartmentId) references Department(DeptId)  
  42.   
  43. alter table UserRoleMapping Add foreign key(UserId)  
  44. references Users(Id)  
  45.   
  46. alter table UserRoleMapping Add foreign key(RoleId)  
  47. references Roles(id)  
Step 2
 
Open Visual Studio 2015 or an editor of your choice and create a new project.
 
Step 3
 
Choose "web application" project and give an appropriate name to your project.
 
Role Based Authentication In ASP.NET MVC
 
Step 4
 
Select "empty" template, check on the MVC box, and click OK.
 
Role Based Authentication In ASP.NET MVC
 
Step 5 
 
Right-click on the Models folder and add a database model. Add Entity Framework now. For that, right-click on Models folder, select Add, then select New Item.
 
Role Based Authentication In ASP.NET MVC
 
You will get a window; from there, select Data from the left panel and choose ADO.NET Entity Data Model, give it the name EmployeeModel (this name is not mandatory, you can give any name) and click "Add".
 
Role Based Authentication In ASP.NET MVC
 
After you click on "Add a window", the wizard will open. Choose EF Designer from the database and click "Next".
 
Role Based Authentication In ASP.NET MVC
 
After clicking on "Next", a window will appear. Choose New Connection. Another window will appear. Add your server name - if it is local, then enter a dot (.). Choose your database and click "OK".
 
Role Based Authentication In ASP.NET MVC
 
The connection will be added. If you wish, save the connection name as you want. You can change the name of your connection below. It will save the connection in the web config. Now, click "Next".
 
Role Based Authentication In ASP.NET MVC
 
After clicking on NEXT, another window will appear. Choose the database table name as shown in the below screenshot and click "Finish".
 
Role Based Authentication In ASP.NET MVC
 
Entity Framework gets added and the respective class gets generated under the Models folder.
 
Role Based Authentication In ASP.NET MVC
 
Step 6
 
Right-click on Controllers folder and add a controller.
 
Role Based Authentication In ASP.NET MVC
 
A window will appear. Choose MVC5 Controller with views, using Entity Framework and click "Add".
 
Role Based Authentication In ASP.NET MVC
 
After clicking on "Add", another window will appear. Choose Model Class and data context class and click "Add". The EmployeesController will be added under the Controllers folder with respective views.
 
Role Based Authentication In ASP.NET MVC
 
Modify Employees Controller Code 
  1. using MvcRoleBasedAuthentication_Demo.Models;  
  2. using System.Data.Entity;  
  3. using System.Linq;  
  4. using System.Net;  
  5. using System.Web.Mvc;  
  6.    
  7. namespace MvcRoleBasedAuthentication_Demo.Controllers  
  8. {  
  9.    
  10.     public class EmployeesController : Controller  
  11.     {  
  12.         private EmployeeContext db = new EmployeeContext();  
  13.    
  14.         [Authorize(Roles ="Admin,Employee")]  
  15.         public ActionResult Index()  
  16.         {  
  17.             var employees = db.Employees.Include(e => e.Department);  
  18.             return View(employees.ToList());  
  19.         }  
  20.    
  21.         [Authorize(Roles = "Admin,Employee")]  
  22.         public ActionResult Details(int? id)  
  23.         {  
  24.             if (id == null)  
  25.             {  
  26.                 return new HttpStatusCodeResult(HttpStatusCode.BadRequest);  
  27.             }  
  28.             Employee employee = db.Employees.Find(id);  
  29.             if (employee == null)  
  30.             {  
  31.                 return HttpNotFound();  
  32.             }  
  33.             return View(employee);  
  34.         }  
  35.    
  36.         [Authorize(Roles = "Employee")]  
  37.         public ActionResult Create()  
  38.         {  
  39.             ViewBag.DepartmentId = new SelectList(db.Departments, "DeptId""DepartmentName");  
  40.             return View();  
  41.         }  
  42.    
  43.         [Authorize(Roles = "Employee")]  
  44.         [HttpPost]  
  45.         [ValidateAntiForgeryToken]  
  46.         public ActionResult Create([Bind(Include = "EmpId,Name,Gender,Age,Position,Office,HireDate,Salary,DepartmentId")] Employee employee)  
  47.         {  
  48.             if (ModelState.IsValid)  
  49.             {  
  50.                 db.Employees.Add(employee);  
  51.                 db.SaveChanges();  
  52.                 return RedirectToAction("Index");  
  53.             }  
  54.    
  55.             ViewBag.DepartmentId = new SelectList(db.Departments, "DeptId""DepartmentName", employee.DepartmentId);  
  56.             return View(employee);  
  57.         }  
  58.    
  59.         [Authorize(Roles = "Employee")]  
  60.         public ActionResult Edit(int? id)  
  61.         {  
  62.             if (id == null)  
  63.             {  
  64.                 return new HttpStatusCodeResult(HttpStatusCode.BadRequest);  
  65.             }  
  66.             Employee employee = db.Employees.Find(id);  
  67.             if (employee == null)  
  68.             {  
  69.                 return HttpNotFound();  
  70.             }  
  71.             ViewBag.DepartmentId = new SelectList(db.Departments, "DeptId""DepartmentName", employee.DepartmentId);  
  72.             return View(employee);  
  73.         }  
  74.    
  75.         [Authorize(Roles = "Employee")]  
  76.         [HttpPost]  
  77.         [ValidateAntiForgeryToken]  
  78.         public ActionResult Edit([Bind(Include = "EmpId,Name,Gender,Age,Position,Office,HireDate,Salary,DepartmentId")] Employee employee)  
  79.         {  
  80.             if (ModelState.IsValid)  
  81.             {  
  82.                 db.Entry(employee).State = EntityState.Modified;  
  83.                 db.SaveChanges();  
  84.                 return RedirectToAction("Index");  
  85.             }  
  86.             ViewBag.DepartmentId = new SelectList(db.Departments, "DeptId""DepartmentName", employee.DepartmentId);  
  87.             return View(employee);  
  88.         }  
  89.    
  90.         [Authorize(Roles = "Admin,Employee")]  
  91.         public ActionResult Delete(int? id)  
  92.         {  
  93.             if (id == null)  
  94.             {  
  95.                 return new HttpStatusCodeResult(HttpStatusCode.BadRequest);  
  96.             }  
  97.             Employee employee = db.Employees.Find(id);  
  98.             if (employee == null)  
  99.             {  
  100.                 return HttpNotFound();  
  101.             }  
  102.             return View(employee);  
  103.         }  
  104.    
  105.         [Authorize(Roles = "Admin,Employee")]  
  106.         [HttpPost, ActionName("Delete")]  
  107.         [ValidateAntiForgeryToken]  
  108.         public ActionResult DeleteConfirmed(int id)  
  109.         {  
  110.             Employee employee = db.Employees.Find(id);  
  111.             db.Employees.Remove(employee);  
  112.             db.SaveChanges();  
  113.             return RedirectToAction("Index");  
  114.         }  
  115.    
  116.         protected override void Dispose(bool disposing)  
  117.         {  
  118.             if (disposing)  
  119.             {  
  120.                 db.Dispose();  
  121.             }  
  122.             base.Dispose(disposing);  
  123.         }  
  124.     }  
  125. }  
Step 6
 
Right click on Models folder and create a UserRoleProvider class,
 
Role Based Authentication In ASP.NET MVC
 
Role Based Authentication In ASP.NET MVC
 
UserRoleProvider Class 
  1. using System;  
  2. using System.Linq;  
  3. using System.Web.Security;  
  4.    
  5. namespace MvcRoleBasedAuthentication_Demo.Models  
  6. {  
  7.     public class UserRoleProvider : RoleProvider  
  8.     {  
  9.         public override string ApplicationName  
  10.         {  
  11.             get  
  12.             {  
  13.                 throw new NotImplementedException();  
  14.             }  
  15.    
  16.             set  
  17.             {  
  18.                 throw new NotImplementedException();  
  19.             }  
  20.         }  
  21.    
  22.         public override void AddUsersToRoles(string[] usernames, string[] roleNames)  
  23.         {  
  24.             throw new NotImplementedException();  
  25.         }  
  26.    
  27.         public override void CreateRole(string roleName)  
  28.         {  
  29.             throw new NotImplementedException();  
  30.         }  
  31.    
  32.         public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)  
  33.         {  
  34.             throw new NotImplementedException();  
  35.         }  
  36.    
  37.         public override string[] FindUsersInRole(string roleName, string usernameToMatch)  
  38.         {  
  39.             throw new NotImplementedException();  
  40.         }  
  41.    
  42.         public override string[] GetAllRoles()  
  43.         {  
  44.             throw new NotImplementedException();  
  45.         }  
  46.    
  47.         public override string[] GetRolesForUser(string username)  
  48.         {  
  49.             using (EmployeeContext _Context=new EmployeeContext())  
  50.             {  
  51.                 var userRoles = (from user in _Context.Users  
  52.                                  join roleMapping in _Context.UserRoleMappings  
  53.                                  on user.Id equals roleMapping.UserId  
  54.                                  join role in _Context.Roles  
  55.                                  on roleMapping.RoleId equals role.Id  
  56.                                  where user.Username == username  
  57.                                  select role.RoleName).ToArray();  
  58.                 return userRoles;  
  59.             }               
  60.         }  
  61.    
  62.         public override string[] GetUsersInRole(string roleName)  
  63.         {  
  64.             throw new NotImplementedException();  
  65.         }  
  66.    
  67.         public override bool IsUserInRole(string username, string roleName)  
  68.         {  
  69.             throw new NotImplementedException();  
  70.         }  
  71.    
  72.         public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)  
  73.         {  
  74.             throw new NotImplementedException();  
  75.         }  
  76.    
  77.         public override bool RoleExists(string roleName)  
  78.         {  
  79.             throw new NotImplementedException();  
  80.         }  
  81.     }  
  82. }  
Step 7
 
Open web config file and write the following code.
  1. <authentication mode="Forms">  
  2.       <forms loginUrl="Account/Login"></forms>  
  3.     </authentication>  
  4.     <roleManager defaultProvider="userRoleProvider" enabled="true">  
  5.       <providers>  
  6.         <clear/>  
  7.         <add name="userRoleProvider" type="MvcRoleBasedAuthentication_Demo.Models.UserRoleProvider"/>  
  8.       </providers>  
  9.     </roleManager>  
Step 8
 
Open _Layout.cshtml file which under views folder in shared folder.
  1. <nav class="navbar navbar-expand-md bg-dark navbar-dark">  
  2.         <a class="navbar-brand" href="#">  
  3.             @Html.ActionLink("Application name""Index""Home"new { area = "" }, new { @class = "navbar-brand" })  
  4.         </a>  
  5.         <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#collapsibleNavbar">  
  6.             <span class="navbar-toggler-icon"></span>  
  7.         </button>  
  8.         <div class="collapse navbar-collapse" id="collapsibleNavbar">  
  9.             <ul class="navbar-nav">  
  10.                 @if (User.Identity.IsAuthenticated)  
  11.                 {  
  12.                     <li class="nav-item">  
  13.                         @Html.ActionLink("List""Index""Employees"new { @class = "nav-link" })  
  14.                     </li>  
  15.                     <li class="nav-item">  
  16.                         @Html.ActionLink("Add New""Create""Employees"new { @class = "nav-link" })  
  17.                     </li>  
  18.                     <li class="nav-item">  
  19.                         @Html.ActionLink("Hello ->" + @User.Identity.Name, """"new { @class = "nav-link" })  
  20.                     </li>  
  21.                     <li class="nav-item">  
  22.                         @Html.ActionLink("Logout""Logout""Account"new { @class = "nav-link" })  
  23.                     </li>  
  24.                 }  
  25.                 else  
  26.                 {  
  27.                     <li class="nav-item">  
  28.                         @Html.ActionLink("Login""Login""Account"new { @class = "nav-link" })  
  29.                     </li>  
  30.                 }  
  31.             </ul>  
  32.         </div>  
  33.     </nav>