Code beautifier used: http://hilite.me/
Usage:
[CustomAuthorize] public class AdministrationController : BaseController { #region Users List [NavigationMenuEnumAuthorize(NavigationMenuEnum.UserAdministration)] public ActionResult Index() { return View(); } }
CustomAuthorizeAttrbute Code:
namespace System.ComponentModel.DataAnnotations { public class NavigationMenuEnumAuthorizeAttribute : System.Attribute { public List NavigationMenuEnumList { get; set; } public NavigationMenuEnumAuthorizeAttribute(params NavigationMenuEnum[] navigationPages) { NavigationMenuEnumList = new List(); if (navigationPages != null && navigationPages.Count() > 0) { NavigationMenuEnumList = navigationPages.ToList(); } } } public class CustomAuthorizeAttribute : System.Web.Mvc.AuthorizeAttribute { string currentAction; string currentController; string currentArea; public override void OnAuthorization(System.Web.Mvc.AuthorizationContext filterContext) { base.OnAuthorization(filterContext); } protected override bool AuthorizeCore(HttpContextBase httpContext) { var routeData = httpContext.Request.RequestContext.RouteData; currentAction = routeData.GetRequiredString("action"); currentController = routeData.GetRequiredString("controller"); currentArea = routeData.Values["area"] as string; if (Utils.CurrentUser == null) return false; Dictionary<NavigationMenuEnum, bool> menuSecurity = new Dictionary<NavigationMenuEnum, bool>(); using (var dbContext = new Web.Models.ConnectionStringEDMX()) { int userid = Utils.CurrentUser.UserId; menuSecurity[NavigationMenuEnum.CreateNewForm] = false; menuSecurity[NavigationMenuEnum.CreateNewChildForm] = false; menuSecurity[NavigationMenuEnum.EditNewForm] = false; menuSecurity[NavigationMenuEnum.FormSummary] = false; menuSecurity[NavigationMenuEnum.AllRequests] = false; menuSecurity[NavigationMenuEnum.MyRequests] = false; menuSecurity[NavigationMenuEnum.WaitingForApproval] = false; menuSecurity[NavigationMenuEnum.UserAdministration] = false; menuSecurity[NavigationMenuEnum.Delegate] = false; menuSecurity[NavigationMenuEnum.Reporting] = false; if (userid == 0) { httpContext.Session[Web.Helpers.StaticStrings.MenuSecuritySessionName] = (Dictionary<NavigationMenuEnum, bool>)menuSecurity; return false; } var userRoles = dbContext.admUserRoles.Where(x => x.UserId == userid || Utils.CurrentUser.CurrentUserDelegatedForUserIdList.Contains(x.UserId)); foreach (admUserRole userRole in userRoles) { switch ((EnRoles)userRole.RoleId) { case EnRoles.Admin: { menuSecurity[NavigationMenuEnum.CreateNewForm] = true; menuSecurity[NavigationMenuEnum.CreateNewChildForm] = true; menuSecurity[NavigationMenuEnum.EditNewForm] = true; menuSecurity[NavigationMenuEnum.AllRequests] = true; menuSecurity[NavigationMenuEnum.MyRequests] = true; menuSecurity[NavigationMenuEnum.WaitingForApproval] = true; menuSecurity[NavigationMenuEnum.FormSummary] = true; menuSecurity[NavigationMenuEnum.UserAdministration] = true; menuSecurity[NavigationMenuEnum.Delegate] = true; menuSecurity[NavigationMenuEnum.Reporting] = true; break; } case EnRoles.Originator: { menuSecurity[NavigationMenuEnum.CreateNewForm] = true; menuSecurity[NavigationMenuEnum.CreateNewChildForm] = true; menuSecurity[NavigationMenuEnum.EditNewForm] = true; menuSecurity[NavigationMenuEnum.FormSummary] = true; menuSecurity[NavigationMenuEnum.AllRequests] = true; menuSecurity[NavigationMenuEnum.MyRequests] = true; menuSecurity[NavigationMenuEnum.Delegate] = true; break; } case EnRoles.Reviewer: { menuSecurity[NavigationMenuEnum.AllRequests] = true; menuSecurity[NavigationMenuEnum.WaitingForApproval] = true; menuSecurity[NavigationMenuEnum.FormSummary] = true; menuSecurity[NavigationMenuEnum.Delegate] = true; break; } case EnRoles.Approver: { menuSecurity[NavigationMenuEnum.AllRequests] = true; menuSecurity[NavigationMenuEnum.WaitingForApproval] = true; menuSecurity[NavigationMenuEnum.FormSummary] = true; menuSecurity[NavigationMenuEnum.Delegate] = true; break; } case EnRoles.Reporting: { menuSecurity[NavigationMenuEnum.AllRequests] = true; menuSecurity[NavigationMenuEnum.Reporting] = true; menuSecurity[NavigationMenuEnum.Delegate] = true; break; } case EnRoles.Viewer: { menuSecurity[NavigationMenuEnum.AllRequests] = true; menuSecurity[NavigationMenuEnum.Delegate] = true; menuSecurity[NavigationMenuEnum.FormSummary] = true; break; } case EnRoles.Supervisor: { menuSecurity[NavigationMenuEnum.AllRequests] = true; menuSecurity[NavigationMenuEnum.WaitingForApproval] = true; menuSecurity[NavigationMenuEnum.FormSummary] = true; menuSecurity[NavigationMenuEnum.Delegate] = true; break; } default: { break; } } } } httpContext.Session[Web.Helpers.StaticStrings.MenuSecuritySessionName] = (Dictionary<NavigationMenuEnum, bool>)menuSecurity; List pageMapping = GetGeneralPageDetailsList(); // all page mappings are generating from controllers that have the CustomAuthorizeAttribute and Actions that have the NavigationMenuEnumAuthorizeAttribute if (!pageMapping.Any(x => x.Action == currentAction && x.Controller == currentController)) return true; NavigationMenuEnum currentPage = pageMapping.Where(x => x.Action == currentAction && x.Controller == currentController).Select(x => x.Page).FirstOrDefault(); return menuSecurity[currentPage]; } public class PageDetails { public string Action { get; set; } public string Controller { get; set; } public NavigationMenuEnum Page { get; set; } public PageDetails(string action, string controller, NavigationMenuEnum page) { this.Action = action; this.Controller = controller; this.Page = page; } } protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) { if (Utils.CurrentUser == null || Utils.CurrentUser.UserId == 0) { filterContext.Result = new RedirectToRouteResult( new RouteValueDictionary { { "area", "" }, { "controller", "Home" }, { "action", "SignIn" } }); } else { filterContext.Result = new RedirectToRouteResult( new RouteValueDictionary { { "area", "" }, { "controller", "Account" }, { "action", "NoAccess" } }); } return; base.HandleUnauthorizedRequest(filterContext); } /// https://stackoverflow.com/a/11305443/249895 public List GetGeneralPageDetailsList() { try { ///https://stackoverflow.com/a/30969888/249895 Assembly asm = Assembly.GetAssembly(typeof(MvcApplication)); var controllerTypesList = asm.GetTypes().Where(type => typeof(System.Web.Mvc.Controller).IsAssignableFrom(type)); var returnPagesList = new List(); foreach (var controllerType in controllerTypesList) { var reflectedControllerDescriptor = new ReflectedControllerDescriptor(controllerType); string controllerName = reflectedControllerDescriptor.ControllerName; var customAuthorizeAttributeList = reflectedControllerDescriptor.GetCustomAttributes(typeof(CustomAuthorizeAttribute), true); if (customAuthorizeAttributeList != null && customAuthorizeAttributeList.Count() > 0) { var actionsList = reflectedControllerDescriptor.GetCanonicalActions(); foreach (var action in actionsList) { var attributesList = action.GetCustomAttributes(typeof(NavigationMenuEnumAuthorizeAttribute), true).Select(x => (NavigationMenuEnumAuthorizeAttribute)x).ToList(); if (attributesList != null && attributesList.Count() > 0) { foreach (var attribute in attributesList) { foreach (var navigMenuEnum in attribute.NavigationMenuEnumList) { var page = new CustomAuthorizeAttribute.PageDetails(action.ActionName, controllerName, navigMenuEnum); returnPagesList.Add(page); } } } else { var page = new CustomAuthorizeAttribute.PageDetails(action.ActionName, controllerName, NavigationMenuEnum.None); returnPagesList.Add(page); } } } } return returnPagesList; } catch (ReflectionTypeLoadException ex) { System.Text.StringBuilder sb = new System.Text.StringBuilder(); foreach (Exception exSub in ex.LoaderExceptions) { sb.AppendLine(exSub.Message); System.IO.FileNotFoundException exFileNotFound = exSub as System.IO.FileNotFoundException; if (exFileNotFound != null) { if (!string.IsNullOrEmpty(exFileNotFound.FusionLog)) { sb.AppendLine("Fusion Log:"); sb.AppendLine(exFileNotFound.FusionLog); } } sb.AppendLine(); } string errorMessage = sb.ToString(); Elmah.ErrorSignal.FromCurrentContext().Raise(ex); Exception newEx = new Exception(errorMessage); Elmah.ErrorSignal.FromCurrentContext().Raise(newEx); throw newEx; //Display or log the error based on your application. } catch (Exception ex) { Elmah.ErrorSignal.FromCurrentContext().Raise(ex); throw; } } } }