asp.net mvc 3的微小自定义角色管理

时间:2012-02-28 09:01:32

标签: asp.net asp.net-mvc-3 entity-framework-4 user-management

我选择使用asp.net mvc3进行学校项目,需要用户/角色管理。我认为asp.net附带的会员资格对于学校项目来说太大了。 我的想法是这样的。如果我能找到相当于Zend predispatch方法的asp甚至更好的方法我可以存储可作为角色权限访问的URL并将其加载到会话中并检查特定用户是否可以访问它并重定向(如果不是)

我的问题是:

asp中是否有等效的PreDispatch方法? 对我的问题有没有更好的方法?如果是,请发布资源

感谢您阅读本文

修改 我使用以下方法从数据库生成子链接:

 public static class SubMenuHelper
{


    public static MvcHtmlString GetSubMenu()
    {
        var db = new SchoolContextExpress();
        var submenu = from s in db.Disciplines select s;
        var sbuilder = new StringBuilder();
        foreach (var discipline in submenu)
        {
            sbuilder.AppendFormat("<li><a class='sublink' href='/Discipline/Details/{0}'>{1}</a></li>", discipline.DisciplineID, discipline.Name);
        }
        return new MvcHtmlString(sbuilder.ToString());
    }
}

1 个答案:

答案 0 :(得分:4)

你可以这样实现。

  1. 角色的枚举
  2. FilterAttribute
  3. 为菜单
  4. 创建Web.sitemap
  5. 添加菜单创建者操作
  6. 将菜单添加到_Layout.cshtml
  7. 将FilterAttribute添加到控制器或操作
  8. ---- 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)
        {
            // Ajax requests will return status code 500 because we don't want to return the result of the
            // redirect to the login page.
            if (filterContext.RequestContext.HttpContext.Request.IsAjaxRequest())
            {
                filterContext.Result = new HttpStatusCodeResult(500);
            }
            else
            {
                filterContext.Result = new RedirectToRouteResult("Error - 401", null);
            }
        }
        public HttpValidationStatus OnCacheAuthorization(HttpContextBase httpContext)
        {
            var success = false;
    
            foreach (Roles role in _requiredRoles)
            {
                success |= _authManager.HasPermission(role);
            }
    
            if (success)
            {
                return HttpValidationStatus.Valid;
            }
            else
            {
                return HttpValidationStatus.IgnoreThisRequest;
            }
        }
    }
    

    ---- 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菜单创建者动作----

    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将助手添加到_Layout.cshtml

      @Html.Action("NavigationMenu", "Common")
    

    ---- 6控制器----

    [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;
        }
    }