2009-08-22 218 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

实施您自己的角色提供程序并设置您的应用程序使用它。然后,授权属性将尊重您的无条件代码。

相关问题