0

私はasp.net mvc3で学校プロジェクトを行い、ユーザー/ロール管理の必要があります。 asp.netに同梱されているメンバーシップは、学校のプロジェクトにとっては大きすぎると思います。 私の考えはこれです。私はZend predispatchのASPの同等の方法を見つけることができた場合、またはより良い1つ私はロールのアクセス権としてアクセス可能なURLを格納し、セッションでロードし、特定のユーザーがそれにアクセスしていない場合はリダイレクトを確認します。asp.net mvc 3の小さなカスタムロール管理

私の質問はこれです:

は、ASPでPreDispatch方法の任意の等価はありますか?
私の問題に対して、より良いアプローチがありますか?はいこの

EDIT を読み取るためのリソース

感謝を投稿してください場合、私はこれを使用して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

あなたはこのように実装することができます。役割

  • FilterAttribute
  • ため

    1. 列挙型メニュー作成者アクション
    をコントローラやアクションにFilterAttributeを追加
  • を_Layout.cshtmlするメニューを追加メニュー
  • ため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は

    0を_Layout.cshtmlするヘルパーを追加します。
    @Html.Action("NavigationMenu", "Common") 
    

    ---- 6 ----コントローラ

    [RequirePermissionFilter(Roles.Student)] 
    public class StudentController : Controller{ 
        /* 
        * 
        * 
        * 
        * 
        */ 
    
    } 
    

    ----認証マネージャー---

    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から規律のサブメニューを生成します。ロールはデータベースからのものでもあります。投稿を更新してサブメニューの作成方法を含めるようにします。 –

    +0

    認証は 'RequirePermissionFilter'フィルタで行われます。このような最小限の役割を果たす必要があります。 '[RequirePermissionFilter(Roles.Student)]'。認証時にセッションにユーザロールを追加する必要があります。ユーザーが必要最小限の役割を果たす場合は、セッションオブジェクトを確認します。 – Yorgo

    +0

    私は、データベースからのログイン後に起こるシナリオを意味します。 '1'渡されたユーザー名/パスワードに対応するユーザーを見つけました。 ' 2'そのユーザーオブジェクトをセッションに格納します。 '3'私はRequirePermissionをロールそれそれ '4'フィルタ開始の各注釈付きコントローラのロールを開始すると良いですか? –