【问题标题】:Overriding default [Authorize] behavior in MVC5?覆盖 MVC5 中的默认 [Authorize] 行为?
【发布时间】:2014-04-04 18:30:06
【问题描述】:

我想覆盖 [Authorize] 属性的默认行为。我找到了这个 similar question,但它已经很老了,而且 MVC 自发布以来已经进行了几次迭代。

我不希望创建单独的“自定义”属性类并将该属性应用于所有控制器/操作,以便将未经授权的请求发送到单独的控制器/操作。我希望能够在全局范围内执行此操作并影响已配置有 [Authorize] 属性的所有控制器/操作。

这可能吗?

【问题讨论】:

  • 没有。通过使用Authorize 装饰您的控制器或动作,您将其耦合到AuthorizeAttribute 对象。显然,您无法编辑该对象的源代码,除非您想构建自己的 MVC 程序集:) 您最好的办法是从它派生并覆盖其他帖子中详述的适当方法。
  • 感谢@ChrisHardie!我已经更新了我上面的帖子,说明我是如何使用自定义属性完成这项工作的。
  • FWIW,这不是AuthorizeAttribute。它为仍然无权访问特定操作的经过身份验证的用户返回正确的 403 响应。表单身份验证实际上是这里的罪魁祸首。它拦截both 401(未经身份验证)和403(经过身份验证,但未经授权)并重定向到登录页面。似乎也没有办法阻止这种情况。在返回 401 或 403 之前,您可以在操作 (ASP.NET 4.5+) 中手动禁用重定向,但不能在全局范围内,也不能仅针对两个状态代码之一。

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


【解决方案1】:

好的。由于无法在全局和就地覆盖 [Authorize] 属性,因此我是这样做的。

在您的应用程序的全局命名空间中创建一个新的自定义AuthorizeAttribute 类(我叫我的CustomAuthorizeAttribute)。我将这个类文件放在一个名为 Extend 的文件夹中(我在扩展 MVC 框架时放置了所有自定义类)并确保命名空间与我的应用程序的根命名空间相同(这样所有控制器都可以“看到'它)。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace CustomProject
{
    public class CustomAuthorizeAttribute : AuthorizeAttribute
    {
        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            System.Web.Routing.RouteValueDictionary rd;
            if (filterContext.HttpContext.User.Identity.IsAuthenticated)
            {
                rd = new System.Web.Routing.RouteValueDictionary(new { action = "NotAuthorized", controller = "Error" });
            }
            else
            {
                //user is not authenticated
                rd = new System.Web.Routing.RouteValueDictionary(new { action = "Login", controller = "Account" });
            }
            filterContext.Result = new RedirectToRouteResult(rd);
        }
    }
}

我的CustomAuthorizeAttribute 考虑了经过身份验证的用户场景并适当地重新路由/重定向。

然后,您需要将[CustomAuthorize(Roles="Admin")](使用您为应用程序配置的角色)添加到您想要审查的控制器和/或操作中。

此外,我创建了一个ErrorController 来处理错误,并根据我的需要添加了一个“未授权”操作。如果你愿意,你当然可以扩展它。也许包括一些日志记录?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace HypeKick.BankUI.Controllers
{
    public class ErrorController : Controller
    {
        //
        // GET: /Error/
        public ActionResult Index()
        {
            return View();
        }

        public ActionResult NotAuthorized()
        {
            return View();
        }
}
}

不要忘记创建必要的视图!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-10
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多