You can implement this.
- Enumeration for Roles
- FilterAttribute
- Create Web.sitemap Map for Menu
- Add Menu Creator Action
- Add menu to _Layout.cshtml
- Add FilterAttribute to a controller or action
---- 1 Enum ------
public enum Roles{ Common=1, Student = 2, Teacher=4 Administration=8 }
---- 2 RequirePermissionFilter ----
public class RequirePermissionFilter : ActionFilterAttribute, IAuthorizationFilter { private readonly Roles[] _requiredRoles; public RequirePermissionFilter(Roles requiredRoles) { _requiredRoles = new Roles[] { requiredRoles }; } public RequirePermissionFilter(Roles[] requiredRoles) { _requiredRoles = requiredRoles; } public void OnAuthorization(AuthorizationContext filterContext) { var success = false; foreach (Roles role in _requiredRoles) { success |= _authManager.HasPermission(role); } if (success) { var cache = filterContext.HttpContext.Response.Cache; cache.SetProxyMaxAge(new TimeSpan(0)); cache.AddValidationCallback((HttpContext context, object data, ref HttpValidationStatus validationStatus) => { validationStatus = this.OnCacheAuthorization(new HttpContextWrapper(context)); }, null); } else { this.HandleUnauthorizedRequest(filterContext); } } private void HandleUnauthorizedRequest(AuthorizationContext filterContext) {
---- 3 Web.sitemap -----
<?xml version="1.0" encoding="utf-8" ?> <siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" > <siteMapNode url="" roleName="" title="" menuVisible="True"> <siteMapNode url="~/Home/Index" roleName="-1" title="Home" menuVisible="True"/> <siteMapNode url="~/Student/Index" roleName="2 title="Student" menuVisible="True"> <siteMapNode url="~/MyLessons/Index" roleName="2 title="My Lessons" menuVisible="True"/> </siteMapNode> <siteMapNode url="~/Teacher/Index" roleName="4 title="Teacher" menuVisible="True"/> <siteMapNode url="~/Administration/Index" roleName="8 title="Administration" menuVisible="True"/> </siteMapNode> </siteMap>
---- 4 Menu Creator Action ----
public class CommonController : Controller{ public ActionResult NavigationMenu() { return Content(SiteMapMenu()); } public string SiteMapMenu() { StringBuilder sb = new StringBuilder(); sb.Append("<div class='menu'><ul>"); var topLevelNodes = SiteMap.RootNode.ChildNodes; foreach (SiteMapNode node in topLevelNodes) { if (HasPermission(node) && IsVisible(node)) { if (SiteMap.CurrentNode == node) sb.Append("<li class='selectedMenuItem'>"); else sb.Append("<li>"); if (!string.IsNullOrEmpty(node.Url)) sb.AppendFormat("<a href='{0}'>{1}</a>", Url.Content(node.Url), node.Title); else sb.AppendFormat("<a href='javascript:void(0)'>{0}</a>", node.Title); if (node.HasChildNodes && AnyOfChildIsVisible(node)) { foreach (SiteMapNode childNode in node.ChildNodes) { if (HasPermission(childNode) && IsVisible(childNode)) { sb.Append("<li>"); sb.AppendFormat("<a href='{0}'>{1}</a>", Url.Content(childNode.Url), childNode.Title); sb.Append("</li>"); } } sb.Append("</ul></div>"); } sb.AppendLine("</li>"); } } sb.AppendLine("</ul></div>"); return sb.ToString(); } private bool HasPermission(SiteMapNode node) { int roleName = int.Parse(node["roleName"].ToString()); if ((roleName == -1) || (_authManager.HasPermission((Roles)roleName))) return true; return false; } private bool IsVisible(SiteMapNode node) { return bool.Parse(node["menuVisible"]); } private bool AnyOfChildIsVisible(SiteMapNode node) { foreach (SiteMapNode item in node.ChildNodes) { if (IsVisible(item)) return true; } return false; } }
---- 5 Add a helper to _Layout.cshtml
@Html.Action("NavigationMenu", "Common")
---- 6 Controller ----
[RequirePermissionFilter(Roles.Student)] public class StudentController : Controller{ }
---- AuthManager ---
public interface IAuthManager { bool HasPermission(Roles requiredRole); } public class AuthManager : IAuthManager { private ISessionManager _sessionManager; private ISuggestionConfig _config; public bool HasPermission(Roles requiredRoles) { if (HttpContext.Current.Session["USER"] != null) return (requiredRoles & ((User)HttpContext.Current.Session["USER"]).Roles) == requiredRoles; else return false; } }
source share