【问题标题】:Is it possible to override the default behavior of [Authorize] in ASP.NET MVC?是否可以覆盖 ASP.NET MVC 中 [Authorize] 的默认行为?
【发布时间】:2009-08-22 08:45:09
【问题描述】:

我想知道是否/如何可以覆盖 ASP.NET MVC 中的默认 [Authorize] 行为。我知道我可以创建一个新的动作过滤器,制作我自己的属性等等;如果我可以简单地更改 [Authorize] 行为并用我自己的代码替换它的工作方式,我只是感兴趣?

编辑:男生和女生。感谢您的意见,但正如我所写,我希望引入新的 [XYZAuthorize] 属性。我知道如何做到这一点。我想保留 [Authorize] 符号,但只是改变它的工作方式。

【问题讨论】:

  • 为什么要保留属性的“授权”名称并更改其行为?这是一件坏事。人们,当他们看到[授权]时,他们期望它会做什么。如果你改变它,阅读你的代码会困难得多。甚至为你在未来。
  • 我不同意;如果您对此提出异议,那么任何运算符或方法的重载/覆盖都是错误的。
  • @Alex:我不同意。运算符重载是一件好事。滥用它是一件坏事。通常的例子:你有一个 Vector 类,你创建了“+”运算符。很明显它会做什么。但是“*”运算符呢?做不好,是叉积还是点积?还是另一种定制产品?所以:重载是好的,但是当你掩盖约定时它是非常糟糕的。
  • 不是专家,我遵循“Bruno Reis”的建议,将其用作单独的 [MyCompanyNameAuthorize] 属性。如何做到这一点的一个例子是geekswithblogs.net/thomasthedeuce/archive/2009/06/25/…

标签: c# .net asp.net-mvc authorize-attribute action-filter


【解决方案1】:

您可以继承 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 的 MSDN 文档: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)。
    【解决方案3】:

    实现您自己的角色提供者并设置您的应用使用它。然后 Authorize 属性将尊重您的授权代码。

    【讨论】:

      【解决方案4】:

      我只看到两种方法:覆盖 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 文件

      【讨论】:

      【解决方案5】:

      看来您可以像往常一样实现自定义过滤器(如果需要,可以继承 AuthorizeAttribute),然后创建一个继承 ControllerActionInvoker 并覆盖 GetFilters 的新 ActionInvoker。在 GetFilters 中,您调用 base.GetFilters() 来获取过滤器列表,遍历 AuthorizationFilters 并将对 AuthorizeFilter 的调用替换为对自定义过滤器的调用。

      另一种可能的方式是实现自定义成员资格和角色提供程序,具体取决于您要执行的操作。

      【讨论】:

      • 为什么需要一个自定义的 ActionInvoker 只是为了一个简单的授权过滤器?
      • @Bruno:因为似乎没有其他方法可以用 out own 替换框架过滤器,只能创建新的。
      • 但是...为什么要替换框架过滤器?看看我对这个问题的评论。这是一件愚蠢的事情。
      • @Bruno:假设您有一堆来自其他项目/开发人员/任何您不想要或由于没有源代码而无法更改的控制器。您不想使用 SQL Server 来存储用户和角色数据,而是使用其他东西。而且您宁愿不实现自定义成员资格和角色提供程序,因为它们很臃肿而且您很懒惰。就是那个时候!创建自定义提供程序或创建自定义(新)属性可能会更好,但在某些情况下可能需要替换对 AuthorizationFilter 的调用。
      • @svinto 你能展示一个替换 AuthorizeFilter 的例子吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-12
      • 1970-01-01
      相关资源
      最近更新 更多