2016-11-22 11 views
3

カスタム属性でセキュリティの検証を行いたいと思います。良い例は、ユーザーが特定のIDを持つエンティティを取得するためのGETリクエストを作成し、属性内のリクエストをインターセプトし、アクションフィルタに渡してから、そのユーザーがアクセスできるかどうかを判断したい場合です。私の唯一の問題は、エンティティIDを取得する方法です。属性宣言で渡すことはできません。なぜなら、それはすべての要求の代わりに一度初期化されるからです。代わりに、HttpGetまたはHttpPostを指定してコンテキストのURLパラメータに対して解決してエンティティIDを返すように、カスタム属性にURLパターンを与えたいと思います。ここでasp net core mvcでルートセグメントを解決する

は私の属性です:

public class RequireProjectAccessAttribute : TypeFilterAttribute 
{ 
    public string UrlPattern { get; set; } 
    public RequireProjectAccessAttribute(string urlPattern) : base(typeof(RequireProjectAccessFilter)) 
    { 
     UrlPattern = urlPattern; 
     Arguments = new object[] { urlPattern }; 
    } 

    private class RequireProjectAccessFilter : IAsyncActionFilter 
    { 
     private readonly ICurrentSession _currentSession; 
     private readonly string _urlPattern; 

     public RequireProjectAccessFilter(ICurrentSession currentSession, string urlPattern) 
     { 
      _currentSession = currentSession; 
      _urlPattern = urlPattern; 
     } 

     public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) 
     { 
      var projectId = /* some magic to resolve _urlPattern against the current url parameter values */ 
      if (/* user doesn't have access to project */) 
      { 
       context.Result = new UnauthorizedResult(); 
      } 
      else 
      { 
       await next(); 
      } 
     } 
    } 
} 

そして、ここでは、私はそれを使用したい方法です:

[Route("api/[controller]")] 
public class ProjectsController : BaseController 
{ 

    public ProjectsController() 
    { 
    } 

    [RequireProjectAccess("{projectId}")] 
    [HttpGet("{projectId}")] 
    public JsonResult GetById(int projectId) 
    { 
     /* retrieve project */ 
    } 
} 
+0

ます。https://あなたの属性は次のようになります意味

var projectId = context.HttpContext.GetRouteValue(_routeKey)?.ToString(); 

channel9.msdn。 com /ブログ/ Seth-Juarez/Advanced-aspNET-Core-Authorization-with-Barry-Dorrans |このビデオに行き、約30分にスキップしてください。 –

答えて

0

あなただけの値が含まれ、その後、使用する必要があり、ルートキーを提供する必要があります拡張メソッドGetRouteValue(string key)HttpContextオブジェクトを超えています。このよう

public class RequireProjectAccessAttribute : TypeFilterAttribute 
{ 
    public string RouteKey { get; set; } 
    public RequireProjectAccessAttribute(string routeKey) : base(typeof(RequireProjectAccessFilter)) 
    { 
     RouteKey = routeKey; 
     Arguments = new object[] { routeKey }; 
    } 

    private class RequireProjectAccessFilter : IAsyncActionFilter 
    { 
     private readonly ICurrentSession _currentSession; 
     private readonly string _routeKey; 

     public RequireProjectAccessFilter(ICurrentSession currentSession, string routeKey) 
     { 
      _currentSession = currentSession; 
      _routeKey = routeKey; 
     } 

     public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) 
     { 
      var projectId = context.HttpContext.GetRouteValue(_routeKey)?.ToString(); 
      if (/* user doesn't have access to project */) 
      { 
       context.Result = new UnauthorizedResult(); 
      } 
      else 
      { 
       await next(); 
      } 
     } 
    } 
} 

と使用(私はルートキーの名前を渡し気づく):

[RequireProjectAccess("projectId")] 
[HttpGet("{projectId}")] 
public JsonResult GetById(int projectId) 
{ 
    /* retrieve project */ 
} 
+0

これは近いですが、HttpGetがその引数を解決するのとまったく同じ方法でRequireProjectAccessに渡されるものを解決したいと思います。私は "projectId"を渡したくないので、 "{projectId}"を渡してMVCに正しいURLパラメータを使って内部ルートリゾルバを使って解決させたいと思います。 –

+0

私は何かが足りないと思う。 「{projectId}」は既にルーティングによって解決されており、projectIdパラメータをRouteDataで使用できるようになったので、なぜそれをもう一度解決する必要がありますか? –