0

我选择做asp.net MVC3学校的项目和有需要用户/角色管理的。我认为随着asp.net发布的会员资格对于学校项目来说太大了。 所以我的想法是这样的。如果我能找到相当于Zend predispatch方法的asp或者更好的方法,我可以将url作为角色的特权存储,并在会话中加载它,并检查特定用户是否有权访问它,如果不是,则重定向。微小的自定义角色管理asp.net的MVC 3

我的问题是这样的:

是否有ASP PreDispatch方法的任何等效?
有没有更好的方法来解决我的问题?如果是,请上传资源

感谢您阅读本

编辑 我生成使用这个从DATABSE子链路:

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()); 
    } 
} 

回答

4

您可以实现这样的。

  1. 枚举的角色
  2. FilterAttribute
  3. 菜单
  4. 添加菜单制作动作
  5. 添加菜单_Layout.cshtml
  6. 添加FilterAttribute到控制器或者动作
创建Web.sitemap中

---- 1枚举------

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; 
    } 
} 
+0

哇真快,我想我喜欢这种方式,但其中身份验证发生?以及将角色传递给过滤器的位置,同时我还使用帮助程序为databse中的规则生成子菜单。角色来自数据库too.will更新帖子,包括我如何生成子菜单感谢。 'RequirePermissionFilter'过滤器中发生了 – 2012-02-28 10:04:08

+0

认证。你必须像这样通过最低要求的角色; '[RequirePermissionFilter(Roles.Student)]'。您必须将用户角色添加到身份验证的会话中。然后检查会话对象是否具有最低要求的角色。 – Yorgo 2012-02-28 10:30:02

+0

我的意思是从数据库登录后发生的情况。假设我实现了一切,它如何工作在更大的图片 '1'我发现一个用户对应于传递的用户名/密码 '2'我将该用户对象存储在会话中 '3'我通过传递实例化RequirePermission角色 '4'过滤器开始检查每个注释控制器的角色然后很好去? – 2012-02-28 10:44:31