Asp.net-Mvc

ASP.Net MVC 3:反向授權屬性

  • July 12, 2012

我有一個簡單的 ASP.Net MVC 3 應用程序,它有一些控制器和一些很好的操作。

現在,由於這是一個基於使用者的應用程序,大多數控制器操作都需要對使用者進行身份驗證。MVC 使用內置的 Authorize 屬性很好地處理了這個問題,您可以使用它來單獨裝飾控制器和/或操作。

最棒的是您可以將屬性僅應用於控制器,並且該給定控制器的所有操作也將應用它 - 節省了大量輸入;)

但我有一個控制器,可以說,10 個動作。但我希望其中一項操作不應用 Authorize 屬性。

是的,我可以將該屬性應用於其他 9 個並將其從控制器中刪除,這將完全滿足我的需要。但是有沒有辦法讓它應用到控制器並選擇排除其中一個動作?

實際上,想要類似…

[!Authorize]或者[NotAuthorize]

我知道我可以創建一個自定義的來完成這項工作,但我想知道是否有內置的方法可以做到這一點?還是我必須將該屬性應用於所有其他 9 個操作?

Phil Haack 最近寫了一篇部落格文章來處理這個確切的場景:

ASP.NET MVC 3 中的條件過濾器

他的解決方案包括編寫一個自定義的“條件過濾器提供程序”,它允許將過濾條件指定給操作方法的屬性。

細節和推理在他的文章裡,但是程式碼比較簡單。首先,創建過濾器提供程序:

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);
 }
}

然後應用它:

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);

請注意,在 ASP.NET MVC 4.0中添加了一個新屬性,該屬性正是這樣做的:

$$ AllowAnonymous $$

引用自:https://stackoverflow.com/questions/7998450