2017-07-13 15 views
1

私の会社のasp.NET MVC5イントラネットWebサイトを作成しています.Active Directoryのユーザー役割に応じて承認と動的メニューを実装したところで、制限を適用する必要がありますアクセス。私はMSDN/Technetで[Authorize(Role="<YourRole>")]を使用して承認を適用できると私はそれを完全に動作させることを読んだ。私の問題は、私は20種類の役割を持っており、それぞれの役割はDocumentsCategoriesと私のMSSQLデータベースにリンクしています。これは、文書やリソースにアクセスしたい場合は、まずDB内の対応するエントリを見つけなければならないことを意味します(必要があればこれをさらに説明できます)。したがって、[Authorize]属性の認可を実装する場合は、その行が存在するかどうかを確認するためにDBをチェックしなければなりません。私は静的クラスでそれを行うために始めている:ASP.NET MVCで役割の権限を最適化

私のコントローラのアクション・メソッドで次に
public static class CustomRoles 
{ 
    public const string Role1 = "Role1"; 
    public const string Role2 = "Role2"; 
    //And so on ... 
} 

[Authorize(Roles=CustomRoles.Role1+","+CustomRoles.Role2)] 
public ActionResult Index(){} 

あなたが長くて退屈になり、それぞれの役割のためにこれをやって想像することができます。

私の質問:あなたはこれを行うためのより簡単な方法を知っていますか?手動で各文書(何千も)をチェックし、別の表でどのようなプロファイルが関連付けられているかを調べ、対応する承認を適用する必要があるためです。そして、技術的には、私のダイナミックメニューはあなたが利用できないものを見ることができないので、これを処理することになっていますが、URLを使って何かにアクセスすることができます。

そしてまた:私のDBにはすべての役割が登録されているわけではありませんが、ほとんどのユーザーは約140の役割を持っていますが、データベースに登録されているのはわずか1または2です。これはパフォーマンス上の問題を引き起こすでしょうか? Claimsを作成してDBに属していないものを除外することができますが、私はそうしたくないと思います。あなたができる

+1

私はあなたが何を望んでいるか分かりませんでしたが、私はあなたの問題を持っていると思います。カスタムのauthorize属性が必要です。この記事をチェックしてください。http://www.diaryofaninja.com/blog/2011/07/24/writing-your-own-custom-aspnet-mvc-authorize-attributesカスタムの書き方を教えています。 – Alexrgs

答えて

1

回避策の一つは、ユーザーが特定のアクションかどうかを実行する権限を与えられたかどうかを確認する代わりに、デコレータAuthorizeAttributeActionFilterOnActionExecuting方法をがオーバーライド使用することです。あなただけ1つの場所、つまり、あなたのアクションフィルタ(または、に、それらのすべてをチェックする必要があるとして、

うん、あなたはまだに慎重あなたのロール認可のチェックが、ないまばらを、必要としますより正確には、シングルswitch)です。また、すべてを1か所に配置することで、冗長性を回避し、可能な限りロジックをよりコンパクトにすることができます。

例:

ActionFilter

public class AuthorizeActionFilterAttribute : ActionFilterAttribute { 
    public override void OnActionExecuting(ActionExecutingContext filterContext) { 

     IPrincipal user = HttpContext.Current.User; //get the current user 

     //Get controller name and action 
     string controllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName; 
     string actionName = filterContext.ActionDescriptor.ActionName; 

     //All roles will be defined here! 
     List<string> rolesAccepted = new List<string>(); 
     switch (controllerName){ 
      case "Controller1": //suppose these three happen to have the same rules 
      case "Controller2": 
      case "Controller3": 
       //Describe roles accepted for certain controller and action 
       rolesAccepted = new List<string> { "Role1", "Role2" };    
       break; 
      case "Controller4": //suppose these have specific restrictions only for some actions 
       if (actionName == "action1") {//can also use switch 
        rolesAccepted = new List<string> { "Role3", "Role4" }; 
       } else { 
        rolesAccepted = new List<string> { "Role5", "Role6", "Role7" }; 
       } 
       break; 
      .... 
     } 

     //Redirect to login if non of the user role is authorized 
     if (!rolesAccepted.Any(x => user.IsInRole(x)){ 
      filterContext.Result = redirectToLogin(); 
      return; 
     } 
    } 

    private ActionResult redirectToLogin() { 
     return new RedirectToRouteResult(
      new RouteValueDictionary(new { controller = "Account", action = "Login" }) 
     ); 
    } 

} 

あなたが1つの場所ですべての許可を扱ってきたように、あなたが唯一の(一つ一つのアクションでの役割ではなく)すべてのコントローラにAuthorizeActionFilterAttributeを配置する必要があり:

[AuthorizeActionFilter] 
public class Controller1 : Controller { 
    ... 
} 

[AuthorizeActionFilter] 
public class Controller2 : Controller { 
    ... 
} 

... and so on 
+1

ああいいよ!これは私が探していたものです、私はそれをテストし、答えとしてマークします。 –

+1

@LéonardLaiterあなたは大歓迎です。チェックアウトしてください! – Ian

+1

それは魅力のように機能します。再びありがとう:) –

関連する問題