|
|
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>
