我想知道是否/如何重写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