2015-11-06 46 views
3

我想实现在MVC6如下:OverrideAuthorizationAttribute在ASP.NET 5

[Authorize(Roles = "Shopper")] 
public class HomeController 
{ 
    [Authorize(Roles = "Editor"), OverrideAuthorization] 
    public IActionResult EditPage() {} 
} 

但OverrideAuthorizationAttribute不再存在。那么如何设置它,以便用户只需要在Editor角色中,而不是EditorShopper角色访问MVC6中的EditPage?

回答

0

我发现this blog post来自Filip W解释了如何使用过滤器提供程序编写自己的解决方案。

但是,该框架已经发生了很大变化,他的解决方案必须进行更新,以考虑框架中的变化,最多可达beta8

首先,您将创建一个新属性,您可以在其中指定要重写的筛选器的类型。 (在你的情况,这将是AuthorizeFilter

public class OverrideFilter : ActionFilterAttribute 
{ 
    public Type Type { get; set; } 
} 

如果你想要的。您可以创建更具体的过滤器,如:

public class OverrideAuhorization : OverrideFilter 
{ 
    public OverrideAuhorization() 
    { 
     this.Type = typeof(AuthorizeFilter); 
    } 
} 

然后,你需要创建一个新的IFilterProvider

  1. 该过滤器提供程序将在框架运行后的默认提供程序 后执行。
  2. 您可以检查 FilterProviderContext.Results并搜索OverrideFilter
  3. 如果找到了,然后你可以检查过滤器的其余部分,并删除 任何过滤器是过滤型的和较低的范围

例如创建一个新的OverrideFriendlyFilterProvider以下这样的想法:

public class OverrideFriendlyFilterProvider : IFilterProvider 
{ 
    //all framework providers have negative orders, so ours will come later 
    public int Order => 1; 

    public void OnProvidersExecuting(FilterProviderContext context) 
    { 
     if (context.ActionContext.ActionDescriptor.FilterDescriptors != null) 
     { 
      //Does the action have any OverrideFilter? 
      var overrideFilters = context.Results.Where(filterItem => filterItem.Filter is OverrideFilter).ToArray(); 
      foreach (var overrideFilter in overrideFilters) 
      {      
       context.Results.RemoveAll(filterItem => 
        //Remove any filter for the type indicated in the OverrideFilter attribute 
        filterItem.Descriptor.Filter.GetType() == ((OverrideFilter)overrideFilter.Filter).Type && 
        //Remove filters with lower scope (ie controller) than the override filter (ie action method) 
        filterItem.Descriptor.Scope < overrideFilter.Descriptor.Scope); 
      } 
     } 
    } 

    public void OnProvidersExecuted(FilterProviderContext context) 
    { 
    } 
} 

您需要注册在你启动类的``ConfigureServices`:

services.TryAddEnumerable(
    ServiceDescriptor.Singleton<IFilterProvider, OverrideFriendlyFilterProvider>()); 

所有这些片段都可以覆盖授权过滤器(或任何其他过滤器)。

例如,在新的MVC应用程序的默认HomeController中,任何登录的用户将能够访问首页行动,但只有管理员角色的那些将能够访问关于行动:

[Authorize] 
public class HomeController : Controller 
{ 
    public IActionResult Index() 
    { 
     return View(); 
    } 

    [Authorize(Roles = "admin"), OverrideAuhorization] 
    public IActionResult About() 
    { 
     return View(); 
    } 
0

我认为最好是使用新的基于策略的授权方法,而不是直接使用角色。

目前还没有关于政策性授权的大量文件,但this article是一个好开始