2016-10-13 35 views
0

私は以下のデータベース構造を持っています DB structure, authentication/authorization part 私はASP.NET MVC 5サイトの認証/承認を構築する必要があります。次のようにASP.NET MVC5でのカスタム認証と承認?

DBスキーマが機能:すべてのusergroupに属し、各groupを付与することができます/ permissionを否定しました。それぞれの許可が(:ListViewAddEditDeleteVoteForVoteAgainstRejectApprove、および各アクションはPermissionsテーブルのエントリですPetitionsコントローラは、次のアクションを持っているでしょう、のは言わせて)、コントローラ上のアクションにマッチします。

すべての目的は、ユーザーがアクションを呼び出すたびに、そのサイトがユーザーがそのアクションに対して許可を与えられたグループに所属していることを確認し、それに応じて反応することです。

例:のは、管理者がUsersグループにManagersグループにPetitionsListPetitionsViewPetitionsApprovePetitionsReject権限を付与し、そしてPetitionsListPetitionsViewPetitionsAddPetitionsVoteForPetitionsVoteAgainstとしましょう。この場合

、両グループは

  • リスト請願

マネージャは

  • が請願を拒否請願を承認することができ嘆願書を表示することができます

しかし、彼らはできません

  • 請願に対する請願
  • 投票の投票。同様に

、ユーザーが

  • は請願

に対する請願

  • 投票の申立て
  • 投票を追加することができますが、彼らがすることはできません。

    • 承認請願
    • は請願

    とどちらの請願を編集または削除することができますを拒否します。

    私は本当にMVC 5の属性機能を活用したいと思います。私の考えは、シーンの背後にあるすべての認証/承認を行うカスタム属性を構築することです。このようなもの:

    public class PetitionsController : Controller 
    { 
        [MyCustomAuth(Permission="PetitionsList",Groups="Users,Managers")] 
        public ActionResult List() 
        { 
         //show the list of petitions 
        } 
    
        [MyCustomAuth(Permission="PetitionsView",Groups="Users,Managers")] 
        public ActionResult View() 
        { 
         //show a specific petition 
        } 
    
        [MyCustomAuth(Permission="PetitionsAdd",Groups="Users")] 
        public ActionResult Add() 
        { 
         //show add petition form 
        } 
    
        [HttpPost] 
        [MyCustomAuth(Permission="PetitionsAdd",Groups="Users")] 
        public ActionResult Add(object[] params) 
        { 
         //save new petition 
        } 
    
        [MyCustomAuth(Permission="PetitionsEdit",Groups="Admins")] 
        public ActionResult Edit(int id) 
        { 
         //show edit petition form 
        } 
    
        [HttpPost] 
        [MyCustomAuth(Permission="PetitionsEdit",Groups="Admins")] 
        public ActionResult Edit(object[] params) 
        { 
         //save changes to petition 
        } 
    
        [HttpPost] 
        [MyCustomAuth(Permission="PetitionsDelete",Groups="Admins")] 
        public ActionResult Delete(int_id) 
        { 
         //delete petition 
        } 
    
        [HttpPost] 
        [MyCustomAuth(Permission="PetitionsVoteFor",Groups="Users")] 
        public ActionResult VoteFor(int id) 
        { 
         //add vote supporting petition 
        } 
    
        [HttpPost] 
        [MyCustomAuth(Permission="PetitionsVoteAgainst",Groups="Users")] 
        public ActionResult VoteAgainst(int id) 
        { 
         //add vote against petition 
        } 
    
        [HttpPost] 
        [MyCustomAuth(Permission="PetitionsApprove",Groups="Managers")] 
        public ActionResult Approve(int id) 
        { 
         //approve petition 
        } 
    
        [HttpPost] 
        [MyCustomAuth(Permission="PetitionsReject",Groups="Managers")] 
        public ActionResult Reject(int id) 
        { 
         //reject petition 
        } 
    } 
    

    各アクションには、MyCustomAuthという属性があります。ユーザーが実際にそのアクションを実行する権限を与えられている場合、その属性が重い吊り上げをしたいと思っています。もちろん、認証/承認されていない場合は、ログインページ/ 401 /別の場所にリダイレクトする必要があります。

    私の質問はどこから始めるのですか?私はMVC 5のいくつかのクラスからいくつかの特別なインターフェイス/継承を実装することを期待していますか?あるいは、これを一から書く必要がありますか?

    また、このテキストの壁を読み、正しい方向に私にヒント/ポインタを与えることに感謝します。

  • +0

    一般的に、データベース・アクセス・コードは(単位はコードをテストすることはできません)属性にすべきではないので、より良い解決策を持っていることであろうユーザーが正しくない許可を持っているかどうかを示す値を返すサービス。各コントローラメソッドのコードは、 'if(!_permissionService.HasPermission(DocumentType.Petitions、ActionType.Edit、user.ID){//拒否} 'のようなものかもしれません。 –

    +0

    指定されたアクションを呼び出して属性クラスからサービスを呼び出す?検証を簡単にテストすることができますが、アクション上の属性のみを書き込むことができます(両方の世界の中で最高のものです)。 –

    +0

    DIを使用して、あなたは2つのトップの回答を見てみることをお勧めします[ここ](http://stackoverflow.com/questions/7192543/injecting-dependencies-into-asp-net-mvc-3-action-filters-whats-wrong-これとともに) –

    答えて

    1

    私は以下のCustom Authorization Filterから始めることができると思います。また、両方の - ajaxリクエストとフルページリクエストのケースも処理します。

    public class MyCustomAuthAttribute : FilterAttribute, IAuthorizationFilter 
        { 
         public string Permission { get; set; } 
         public string Groups { get; set; } 
    
         public void OnAuthorization(AuthorizationContext filterContext) 
         { 
          bool isauthorized = CheckIfUserIsAuthorized(); 
          if (!isauthorized) 
           context.Result = new HttpUnauthorizedResult(); // mark unauthorized 
    
          // Only do something if we are about to give a HttpUnauthorizedResult and we are in AJAX mode. 
          if (filterContext.Result is HttpUnauthorizedResult && filterContext.HttpContext.Request.IsAjaxRequest()) 
          { 
           filterContext.Result = new JsonResult 
           { 
            Data = new { Success = false, Message = "Unauthorized Access" }, 
            JsonRequestBehavior = JsonRequestBehavior.AllowGet 
           }; 
          } 
          else 
          { 
           base.OnAuthorization(filterContext); 
           if (filterContext.Result is HttpUnauthorizedResult) 
           { 
            HttpContext.Current.Session.Abandon(); 
            System.Web.Security.FormsAuthentication.SignOut(); 
            filterContext.Result = new RedirectResult("Your Login Page."); 
           } 
          } 
         } 
    
         private bool IsAuthorizedUser() 
         { 
          // use Permission, Groups and your logic 
         } 
        } 
    

    、あなたが言及したのと同じ方法を使用します。

    [MyCustomAuth(Permission="PetitionsEdit",Groups="Admins")]