即使请求未经授权也会呈现视图

View is rendered even the request is unauthorized

我有一个 MVC 应用程序,其中有一个管理区域。当用户未登录时,我将使用自定义 AuthorizeAttribute 将请求重定向到登录页面。

public class UserAuthorizeAttribute : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        var user = AdminGlobals.CurrentUser;

        if (user == null || !user.IsActive)
        {
            return false;
        }

        return true;
    }

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        var user = AdminGlobals.CurrentUser;
        var context = HttpContext.Current;

        //Do not redirect if the request is already redirecting
        if (context.Response.IsRequestBeingRedirected) return;

        if (user == null || !user.IsActive)
        {
            context.Response.Redirect("/login", true);
        }
        else
        {
            context.Response.Redirect("/unauthorized", true);
        }
    }
}

控制器和动作:

[UserAuthorize]
public ActionResult Index()
{
    return View();
}

在我看来:

Hello @AdminGlobals.CurrentUser.Title

当应用程序处于调试模式时,我在视图内部和布局页面中遇到 NullReferenceExceptions,因为它尝试使用相同的变量 @AdminGlobals.CurrentUser,它是 null。我知道我可以很容易地阻止这种情况,但我不明白为什么在请求未被授权时呈现视图。是否可以在 AuthorizeAttribute 中使用 RedirectToAction 来防止呈现视图?

我不确定在过滤器中使用 Response 是否可行。通常,您利用 filterContext 来执行重定向。例如:

protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
    var user = AdminGlobals.CurrentUser;
    var context = filterContext.HttpContext;

    //Do not redirect if the request is already redirecting
    if (context.Response.IsRequestBeingRedirected) return;

    var routeData = new RouteValueDictionary(new {
        controller = "Home",
        action = "Unauthorized"
    });

    if (user == null || !user.IsActive)
    {
        routeData = new RouteValueDictionary(new { controller = "Home", action = "Login" });
    }

    filterContext.Result = new RedirectToRouteResult("Default", routeData);
}

我从您的代码中假设这两个操作都在 HomeController 上;否则,将控制器名称更新为正确的值。

"Default," 在 RedirectToRouteResult 对象的构造函数中,是您要应用的 RouteConfig 中的路由名称。

此外,使用 filerContext 中的 HttpContext。