2009-08-22 220 views
9

我想知道是否/如何重寫ASP.NET MVC中的默認[授權]行爲。我知道我可以創建一個新的Action Filter,創建自己的屬性等等。我只是感興趣,如果我可以簡單地改變[Authorize]行爲並用我自己的代碼替換它的工作?是否可以重寫ASP.NET MVC中[Authorize]的默認行爲?

編輯:男生和女生。我很欣賞你的輸入,但是正如我寫的,我是而不是希望引入一個新的[XYZAuthorize]屬性。我知道如何做到這一點。我想保留[授權]符號,但只是改變它的工作方式。

+7

爲什麼你想保留屬性的「授權」名稱,並改變它的行爲?這是一件壞事。人們,當他們看到[授權]時,他們期望它會做什麼。如果你改變它,閱讀你的代碼會困難得多。即使對未來你也是如此。 – 2009-08-22 09:31:45

+3

我不同意;如果你認爲這一點,任何操作符或方法重載/覆蓋都是錯誤的。 – Alex 2009-08-22 09:47:31

+5

@亞歷克斯:我不同意。運算符重載是一件好事。濫用它是一件壞事。通常的例子:你有一個Vector類,你創建了「+」運算符。很明顯它會做什麼。但是「*」運算符呢?這是一件壞事,是跨產品還是點積?或另一種定製產品? 所以:重載是好的,但是當你掩蓋慣例時它是非常糟糕的。 – 2009-08-22 09:50:48

回答

6

是的,看看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流水線路由之前從緩存中提供)。

一如既往,您需要了解您的方案以及可用的工具和它們之間的權衡。

+1

AuthorizeAttribute不包含OnAuthorize方法。你的意思是OnAuthorization()?無論如何,你不應該改變它,除非你在實現緩存時需要一些頭痛,因爲它是一種處理它的方法(OnAuthorization)。 – 2009-08-22 09:25:49

9

您可以對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

我看到的只有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文件

+1

如果你不想在頭痛時,你應該避免從頭創建一個授權屬性將實現緩存...來自ASP.NET MVC的Authorize屬性已經處理了這個方面。 – 2009-08-22 09:21:32

1

看起來你可以像往常一樣實現一個自定義過濾器(如果你願意,可以繼承AuthorizeAttribute),然後創建一個新的ActionInvoker,繼承ControllerActionInvoker並覆蓋GetFilters。在GetFilters中,您可以調用base.GetFilters()來獲取過濾器列表,迭代通過AuthorizationFilters並將調用替換爲調用自定義過濾器的AuthorizeFilter。

另一種可能的方法是實現自定義成員資格和角色提供者,具體取決於您要做什麼。

+0

爲什麼需要一個自定義的ActionInvoker只是一個簡單的授權過濾器? – 2009-08-22 09:22:31

+0

@布魯諾:因爲似乎沒有其他方法可以用自己的方法來替換框架過濾器,只是爲了創建新過濾器。 – svinto 2009-08-22 09:31:38

+0

但是...爲什麼要更換框架過濾器呢?看看我對這個問題的評論。這是一件愚蠢的事情。 – 2009-08-22 09:32:35

4

實施您自己的角色提供程序並設置您的應用程序使用它。然後,授權屬性將尊重您的無條件代碼。

相關問題