Asp.net mvc ASP.Net MVC 3:反向授权属性

Asp.net mvc ASP.Net MVC 3:反向授权属性,asp.net-mvc,authentication,attributes,authorize-attribute,Asp.net Mvc,Authentication,Attributes,Authorize Attribute,我有一个简单的ASP.NETMVC3应用程序,它有一些控制器和一些操作 现在,由于这是一个基于用户的应用程序,大多数控制器操作都需要对用户进行身份验证。MVC通过内置的Authorize属性很好地处理了这一问题,您可以使用该属性单独装饰控制器和/或操作 最棒的是,您可以将该属性仅应用于控制器,并且该给定控制器的所有操作也将应用该属性-保存了大量键入;) 但我有一个控制器,比如说,有10个动作。但我希望其中一个操作不应用Authorize属性 是的,我可以将该属性应用于其他9,并将其从控制器中删除

我有一个简单的ASP.NETMVC3应用程序,它有一些控制器和一些操作

现在,由于这是一个基于用户的应用程序,大多数控制器操作都需要对用户进行身份验证。MVC通过内置的Authorize属性很好地处理了这一问题,您可以使用该属性单独装饰控制器和/或操作

最棒的是,您可以将该属性仅应用于控制器,并且该给定控制器的所有操作也将应用该属性-保存了大量键入;)

但我有一个控制器,比如说,有10个动作。但我希望其中一个操作不应用Authorize属性

是的,我可以将该属性应用于其他9,并将其从控制器中删除,这将完全满足我的需要。但是,有没有一种方法可以将其应用于控制器,并选择排除其中一个操作

事实上,我想要的是

[!Authorize]
[NotAuthorize]


我知道我可以创建一个自定义的来完成这项工作,但我想知道的是,是否有一种内置的方法来完成这项工作?或者我必须将该属性应用于所有9个其他操作吗?

菲尔·哈克(Phil Haack)最近写了一篇博客文章,讨论了这个确切的场景:

他的解决方案包括编写一个定制的“条件过滤器提供程序”,允许用户将过滤器条件指定给操作方法的属性

细节和推理在他的帖子中,但代码相对简单。首先,创建筛选器提供程序:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;

public class ConditionalFilterProvider : IFilterProvider {
  private readonly 
    IEnumerable<Func<ControllerContext, ActionDescriptor, object>> _conditions;

  public ConditionalFilterProvider(
    IEnumerable<Func<ControllerContext, ActionDescriptor, object>> conditions)
  {

      _conditions = conditions;
  }

  public IEnumerable<Filter> GetFilters(
      ControllerContext controllerContext, 
      ActionDescriptor actionDescriptor) {
    return from condition in _conditions
           select condition(controllerContext, actionDescriptor) into filter
           where filter != null
           select new Filter(filter, FilterScope.Global, null);
  }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用System.Web.Mvc;
公共类条件过滤器提供程序:IFilterProvider{
私有只读
i可数条件;
公共条件过滤器提供程序(
(可数条件)
{
_条件=条件;
}
公共IEnumerable过滤器(
ControllerContext ControllerContext,
ActionDescriptor(ActionDescriptor){
从_条件中的条件返回
在筛选器中选择条件(controllerContext、actionDescriptor)
其中筛选器!=null
选择新筛选器(筛选器,FilterScope.Global,null);
}
}
然后应用它:

IEnumerable<Func<ControllerContext, ActionDescriptor, object>> conditions = 
    new Func<ControllerContext, ActionDescriptor, object>[] { 

    (c, a) => c.Controller.GetType() != typeof(HomeController) ? 
      new MyFilter() : null,
    (c, a) => a.ActionName.StartsWith("About") ? new SomeFilter() : null
};

var provider = new ConditionalFilterProvider(conditions);
FilterProviders.Providers.Add(provider);
IEnumerable条件=
新函数[]{
(c,a)=>c.Controller.GetType()!=typeof(HomeController)?
新建MyFilter():null,
(c,a)=>a.ActionName.StartsWith(“About”)?new SomeFilter():null
};
var provider=新的条件过滤器provider(条件);
FilterProviders.Providers.Add(提供程序);

请注意,ASP.NET MVC4.0中添加了一个新属性,该属性正是这样做的: