2015-11-06 85 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是一個好開始