我想知道是否/如何重寫ASP.NET MVC中的默認[授權]行爲。我知道我可以創建一個新的Action Filter,創建自己的屬性等等。我只是感興趣,如果我可以簡單地改變[Authorize]行爲並用我自己的代碼替換它的工作?是否可以重寫ASP.NET MVC中[Authorize]的默認行爲?
編輯:男生和女生。我很欣賞你的輸入,但是正如我寫的,我是而不是希望引入一個新的[XYZAuthorize]屬性。我知道如何做到這一點。我想保留[授權]符號,但只是改變它的工作方式。
我想知道是否/如何重寫ASP.NET MVC中的默認[授權]行爲。我知道我可以創建一個新的Action Filter,創建自己的屬性等等。我只是感興趣,如果我可以簡單地改變[Authorize]行爲並用我自己的代碼替換它的工作?是否可以重寫ASP.NET MVC中[Authorize]的默認行爲?
編輯:男生和女生。我很欣賞你的輸入,但是正如我寫的,我是而不是希望引入一個新的[XYZAuthorize]屬性。我知道如何做到這一點。我想保留[授權]符號,但只是改變它的工作方式。
是的,看看MSDN文檔的AuthorizeAttribute:http://msdn.microsoft.com/en-us/library/system.web.mvc.authorizeattribute.aspx。
基本上,您可以重寫OnAuthorization()方法並自定義行爲。該屬性上還有其他虛擬方法。
編輯:正如布魯諾指出的,你可以重寫AuthorizeCore()方法。主要區別在於AuthorizeCore()接受HttpContextBase,而OnAuthorization()接受AuthorizationContext。 AuthorizationContext的一個實例提供了更多的信息,比如Controller,RequestContext和RouteData。它還可以讓你指定一個ActionResult。您可以訪問的信息以及您可以返回的結果中的AuthorizeCore()更受限制,但是如果您需要授權緩存的數據,那麼您的邏輯需要處理您沒有任何這些額外的數據(因爲數據在請求通過MVC流水線路由之前從緩存中提供)。
一如既往,您需要了解您的方案以及可用的工具和它們之間的權衡。
AuthorizeAttribute不包含OnAuthorize方法。你的意思是OnAuthorization()?無論如何,你不應該改變它,除非你在實現緩存時需要一些頭痛,因爲它是一種處理它的方法(OnAuthorization)。 – 2009-08-22 09:25:49
您可以對AuthorizeAttribute過濾器進行子類化,並將其自己的邏輯放入其中。
我們來看一個例子。假設您想要始終授權本地連接。但是,如果它是遠程連接,您希望保留通常的授權邏輯。
你可以這樣做:
public class LocalPermittedAuthorizeAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
return (httpContext.Request.IsLocal || base.AuthorizeCore(httpContext)));
}
}
或者你總是可以授權一定的遠程地址(你的機器,例如)。
就是這樣!
編輯:忘了提,你會用它和你一樣會使用AuthorizeAttribute過濾器:
class MyController : Controller
{
[LocalPermittedAuthorize]
public ActionResult Fire()
{
Missile.Fire(Datetime.Now);
}
}
我看到的只有2種方式:覆蓋AuthorizeAttribute.OnAuthorization
方法或從頭開始創建自己的授權屬性。
1)非常簡單:
public class CustomAuthorizeAttribute : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
/// your behavior here
}
}
2)一件容易的事 - 只要看看ASP.NET MVC源,AuthorizeAttribute.cs文件
如果你不想在頭痛時,你應該避免從頭創建一個授權屬性將實現緩存...來自ASP.NET MVC的Authorize屬性已經處理了這個方面。 – 2009-08-22 09:21:32
看起來你可以像往常一樣實現一個自定義過濾器(如果你願意,可以繼承AuthorizeAttribute),然後創建一個新的ActionInvoker,繼承ControllerActionInvoker並覆蓋GetFilters。在GetFilters中,您可以調用base.GetFilters()
來獲取過濾器列表,迭代通過AuthorizationFilters並將調用替換爲調用自定義過濾器的AuthorizeFilter。
另一種可能的方法是實現自定義成員資格和角色提供者,具體取決於您要做什麼。
爲什麼需要一個自定義的ActionInvoker只是一個簡單的授權過濾器? – 2009-08-22 09:22:31
@布魯諾:因爲似乎沒有其他方法可以用自己的方法來替換框架過濾器,只是爲了創建新過濾器。 – svinto 2009-08-22 09:31:38
但是...爲什麼要更換框架過濾器呢?看看我對這個問題的評論。這是一件愚蠢的事情。 – 2009-08-22 09:32:35
實施您自己的角色提供程序並設置您的應用程序使用它。然後,授權屬性將尊重您的無條件代碼。
爲什麼你想保留屬性的「授權」名稱,並改變它的行爲?這是一件壞事。人們,當他們看到[授權]時,他們期望它會做什麼。如果你改變它,閱讀你的代碼會困難得多。即使對未來你也是如此。 – 2009-08-22 09:31:45
我不同意;如果你認爲這一點,任何操作符或方法重載/覆蓋都是錯誤的。 – Alex 2009-08-22 09:47:31
@亞歷克斯:我不同意。運算符重載是一件好事。濫用它是一件壞事。通常的例子:你有一個Vector類,你創建了「+」運算符。很明顯它會做什麼。但是「*」運算符呢?這是一件壞事,是跨產品還是點積?或另一種定製產品? 所以:重載是好的,但是當你掩蓋慣例時它是非常糟糕的。 – 2009-08-22 09:50:48