我发现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
。
- 该过滤器提供程序将在框架运行后的默认提供程序 后执行。
- 您可以检查
FilterProviderContext.Results
并搜索OverrideFilter
- 如果找到了,然后你可以检查过滤器的其余部分,并删除 任何过滤器是过滤型的和较低的范围
例如创建一个新的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();
}