2016-12-14 2 views
0

私は、アクション特有のアクセス許可データをカスタム認可ポリシーで使用できるようにするために値を渡すアプローチを採用しています。ActionFilterAttributeを使用してASP.NETコアのカスタム認可ポリシーにアクション固有のデータを公開する

問題がありますか? アクション特有のデータを認可要件ハンドラに渡す方法が必要でした。

私は私が権限の多くを持っているので、それはあまりにも多くのポリシーを持っている私を必要とするのでスタートアップ

コントローラ

[Authorize(Policy = "MyPolicy")] 
public IActionResult MyAction() 
    {   
     return View(); 
    } 

services.AddAuthorization(options => 
     {    
      options.AddPolicy("MyPolicy",policy =>policy.Requirements.Add(new PermissionRequirement(PermissionEnum.CanView))); 
     }); 

し、この中でこれを行うにはしたくありませんでした。だから私は、アクションレベルで承認ハンドラにPermissionEnum.CanViewを渡すことができるようにする必要がありました。これにより、各アクションに必要な権限を指定し、同じハンドラでそれらを処理できるようになりました。

私はポリシー属性に値を渡す方法を見つけられなかったので、代わりにこれを行いました。私はその後、私はその後、認可ハンドラで、私はそう

var mvcContext = context.Resource as AuthorizationFilterContext; 
var descriptor = mvcContext?.ActionDescriptor as ControllerActionDescriptor; 

if (descriptor == null) return Task.CompletedTask; 

foreach (var filterMetadata in mvcContext.Filters) 
{ 
if (filterMetadata.GetType().Name != typeof(AccessAttribute).Name) continue; 

var PermissionAttribute = filterMetadata as AccessAttribute; 

if (PermissionAttribute == null) continue; 
if (context.User.HasClaim(c => c.Type == PermissionAttribute.Permission)) 
{ 
context.Succeed(requirement); 
} 
} 

return Task.CompletedTask; 
よう AuthorizationHandlerContextオブジェクトからこの値にアクセスするので、

[Access(PermissionEnum.CanView)] 
[Authorize(Policy = "MyPolicy")] 
public IActionResult MyAction() 
{   
    return View(); 
} 

のようにそれを使用するカスタムActionFilterAttributeを作成し、そこに

public class AccessAttribute : ActionFilterAttribute 
{ 
    public string Permission { get; } 

    public AccessAttribute(PermissionEnum permission) 
    { 
     Permission = permission.ToString(); 
    } 
} 

を値を渡します

ここでは、ユーザーがクレームの形でコンテキストのアクセス許可を与えているので、ユーザーがその操作に対して指定されたアクセス許可を持っているかどうかを確認します。一番下の行は、自分のカスタムフィルタの属性として権限を設定することで、どのユーザーがアクションにアクセスできるかを知ることができるということです。

すべてがうまくいきますが、これが行く方法であるかどうかを知りたいと思います。私は、これを行うより良いアプローチや、カスタムポリシーに値を渡す方法さえあるかもしれないと考えています。

質問:

1)このより良いアプローチがありますか?

2)私は各カスタムフィルタが起動時に2回実行されることをデバッグすることに気付きました。これは問題ではないかもしれませんが、なぜちょうどtwiceが不思議です。彼らは、ハードコードなので、アクションがアクセスされたときには実行されません(これは私にはうまくいきます)。アクションが何回実行されても変化しません。私はこれらについて疑問に思っていますが、私の最初の質問は私の実際の心配です。

答えて

0

[編集]「伝統的な」ASP.NET MVCに基づいており、ASP.NET Core MVCに簡単に対応できます。

ので、私は、各アクションのために必要とされるものの許可を指定し、同じハンドラがそれらを扱う持つことができるように、アクション・レベルでの認証ハンドラにPermissionEnum.CanViewを渡すことができる必要がありました。

オプションは、コンストラクタで許可を受けカスタムAuthorizeAttributeを作成することです:

public class CustomAuthorization : AuthorizeAttribute, IAuthorizationFilter 
{ 
    private readonly string _permission = ""; 

    // use your Enum instead of string   
    public CustomAuthorization(string permission) : base() 
    { 
     _permission = permission; 
    } 

    protected override bool AuthorizeCore(HttpContextBase httpContext) 
    { 
     if (_permission == "xxx" && Roles.Contains("yyyy")) 
     { 
      // do something interesting 
      return true; 
     } 
     return false; 
    } 
} 

とその使用方法:

[CustomAuthorization("My Permission", Roles = "MyRoles")] 
    public ActionResult About() 
    { 
     ViewBag.Message = "Your application description page."; 

     return View(); 
    } 
+0

は、ASP.NETコアのために、このですか? – flexxxit

+0

いいえ、Asp.Net Coreではありません。質問はAsp.net CoreとAsp.Net MVCとしてマークされました。私は "コア部分"を見ていませんでした。そして、私はASP.NET MVCに基づいて応答しました。 –

関連する問題