|
Introduction
In this post, I am going to implement custom Role Provider in Forms authentication in ASP.NET MVC4 application.- In the First part of this series I have implemented very simple and easy authentication.
- In the Second part of this series I have implemented our custom membership provider to take full control of the database and forms authentication mechanism (like validate user, create user, update user, delete user, change password and more).
- Now in this part (Part 3) I would like to implement a custom role provider.
- and In the next part (part 4) We will implement a custom user principal and identity
Here we will implement our custom role provider that will be used to return the roles that a user has to take full control of the database and authorization process mechanism.
Step-1 : Create 2 tables.
Open Database > Right Click on Table > Add New Table > Add Columns > Save > Enter table name > Ok.Table Name : Roles
Step-2: update Entity Data Model.
Go to Solution Explorer > Open Model (created in the part 1) > Right click on empty area (inside model) > Update model from Database > Add Tables > Finish.Step-3 : Add a class for extends RoleProvider class.
Go to solution explorer > Right click on the project name > Add > Class > Enter class name > AddHere we will extend RoleProvider class.
Step-4 : Override two method "GetRolesForUser" and "IsUserInRole" of RoleProvider class.
Complete Codeusing System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Caching; using System.Web.Security; namespace MvcAuthentication { public class MyRoleProvider : RoleProvider { private int _cacheTimeoutInMinute = 20; public override void AddUsersToRoles(string[] usernames, string[] roleNames) { throw new NotImplementedException(); } public override string ApplicationName { get { throw new NotImplementedException(); } set { throw new NotImplementedException(); } } public override void CreateRole(string roleName) { throw new NotImplementedException(); } public override bool DeleteRole(string roleName, bool throwOnPopulatedRole) { throw new NotImplementedException(); } public override string[] FindUsersInRole(string roleName, string usernameToMatch) { throw new NotImplementedException(); } public override string[] GetAllRoles() { throw new NotImplementedException(); } public override string[] GetRolesForUser(string username) { if (!HttpContext.Current.User.Identity.IsAuthenticated) { return null; } //check cache var cacheKey = string.Format("{0}_role", username); if (HttpRuntime.Cache[cacheKey] != null) { return (string[])HttpRuntime.Cache[cacheKey]; } string[] roles = new string[]{}; using (MyDatabaseEntities dc = new MyDatabaseEntities()) { roles = (from a in dc.Roles join b in dc.UserRoles on a.RoleID equals b.RoleID join c in dc.Users on b.UserID equals c.UserID where c.Username.Equals(username) select a.ROleName).ToArray<string>(); if (roles.Count() > 0) { HttpRuntime.Cache.Insert(cacheKey, roles, null, DateTime.Now.AddMinutes(_cacheTimeoutInMinute), Cache.NoSlidingExpiration); } } return roles; } public override string[] GetUsersInRole(string roleName) { throw new NotImplementedException(); } public override bool IsUserInRole(string username, string roleName) { var userRoles = GetRolesForUser(username); return userRoles.Contains(roleName); } public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames) { throw new NotImplementedException(); } public override bool RoleExists(string roleName) { throw new NotImplementedException(); } } }
Step-5: Edit web.config for Enable our custom role provider.
In this example, I have written the following configuration in the web.config file for Enable our custom role provider<roleManager defaultProvider="MyRoleProvider" enabled="true"> <providers> <add name="MyRoleProvider" type="MvcAuthentication.MyRoleProvider, MvcAuthentication"/> </providers> </roleManager>
Step-6: Add new action into your controller (here in HomeController) for "Admin" role user
Here I have used "AdminIndex" Action. Please write this following code[Authorize(Roles="Admin")] public ActionResult AdminIndex() { return View(); }
Step-7: Add view for the Action (here in "AdminIndex") & design.
Right Click on Action Method (here right click on "AdminIndex" action) > Add View... > Enter View Name > Select View Engine (Razor) > Add.@{ ViewBag.Title = "AdminIndex"; } <h2>Admin Index</h2> <div>Welcome @(Request.IsAuthenticated? HttpContext.Current.User.Identity.Name : "") (Admin)</div>
Step-8: Add new action into your controller (here in HomeController) for "User" role user
Here I have used "UserIndex" Action. Please write this following code[Authorize(Roles="User")] public ActionResult UserIndex() { return View(); }
Step-9: Add view for the Action (here in "UserIndex") & design.
Right Click on Action Method (here right click on "UserIndex" action) > Add View... > Enter View Name > Select View Engine (Razor) > Add.@{ ViewBag.Title = "UserIndex"; } <h2>User Index</h2> <div>Welcome @(Request.IsAuthenticated? HttpContext.Current.User.Identity.Name : "") (User) </div>