In previous article I explain how to create Custom Membership Provider to authorize user and protect controls and pages. But what if you want to show or protect some area, controller or page for specific group of users? For example allow access to Admin Panel only for admins.
In .Net Framework for this purpose is Role Provider. But again, it uses own DB for store user roles. So let's create and configure Custom Role Provider which will use our DB or any other storage. As before we should overwrite class from .NET:
For the minimum functionality we need implement and overwrite two functions GetRolesForUser and IsUserInRole. First one is used to gel list of all user roles (or groups):
public override string[] GetRolesForUser(string username) { using (DatabaseEntities db = new DatabaseEntities()) { User user = db.Users.FirstOrDefault(u => u.UserName.Equals(username, StringComparison.CurrentCultureIgnoreCase) || u.Email.Equals(username, StringComparison.CurrentCultureIgnoreCase)); var roles = from ur in user.UserRoles from r in db.Roles where ur.RoleId == r.Id select r.Name; if (roles != null) return roles.ToArray(); else return new string[] {}; ; } }
As you can see I locate user in my DB by username parameter of the function (in my case it’s can be user name or email) and create the string list of user roles.
Second function is to check if user in the role (or group):
public override bool IsUserInRole(string username, string roleName) { using (DatabaseEntities db = new DatabaseEntities()) { User user = db.Users.FirstOrDefault(u => u.UserName.Equals(username, StringComparison.CurrentCultureIgnoreCase) || u.Email.Equals(username, StringComparison.CurrentCultureIgnoreCase)); var roles = from ur in user.UserRoles from r in db.Roles where ur.RoleId == r.Id select r.Name; if (user != null) return roles.Any(r => r.Equals(roleName, StringComparison.CurrentCultureIgnoreCase)); else return false; } }
Then we need to configure in web.config file solution to use created role provider:
<system.web> ... <rolemanager cacherolesincookie="true" defaultprovider="KitsulaRoleProvider" enabled="true"> <providers> <clear /> <add name="KitsulaRoleProvider" type="Kitsula.Security.KitsulaRoleProvider" /> </providers> </rolemanager> ... </system.web>
Now you can protect controllers, actions, pages for specific group of user which are in specified roles by set Authorize attribute:
using System; using System.Web.Mvc; namespace Kitsula.Areas.Admin.Controllers { [Authorize(Roles = "Administrators")] public class HomeController : Controller { // // GET: /Admin/Home/ public ActionResult Index() { return View(); } } }