【问题标题】:global authorization not working - results in blank page rendered全局授权不起作用 - 导致呈现空白页面
【发布时间】:2012-07-18 14:45:10
【问题描述】:

我正在尝试为我的 MVC3 站点实现一个非常基本的登录方案。如果我理解正确,而不是向我的每个控制器类添加 [Authorize] 标记,我应该能够简单地实现一个全局设置。为此,我在 global.asax 中添加了以下内容:

protected void Application_Start()
{
    RegisterGlobalFilters(GlobalFilters.Filters);
}

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new AuthorizeAttribute());  

}

在我的 webconfig 中,我添加了:

<authentication mode="Forms">
   <forms loginUrl="~/Account/LogOn" timeout="2880" />
</authentication>

结果是结果页面完全空白。查看 url,似乎 mvc 按预期重定向到我的登录路由,但页面为空。如果我注释掉 global.asax 中的代码并将 [Authorize] 标记直接放在每个控制器中,它就会按预期工作。

作为一种解决方法,我已经实现了我所阅读的 MVC2 最佳实践,即创建一个 BaseController:Controller 类,向其中添加 [Authorize] 标记,然后更改我所有控制器的固有特性从 BaseController 而不是 Controller 继承。

目前看来效果还不错。

但为什么 global.asax 实现不起作用?

【问题讨论】:

    标签: asp.net-mvc-3 login global-asax authorize-attribute


    【解决方案1】:

    让我们看看这里发生了什么:

    1. 您正在导航到/
    2. 您的全局授权属性生效,由于用户未通过身份验证,因此他被重定向到 ~/Account/LogOn(按照您的 web.config 文件中的说明)进行身份验证
    3. 您的全局授权属性生效,由于用户未通过身份验证,因此他被重定向到 ~/Account/LogOn(按照您的 web.config 文件中的说明)进行身份验证
    4. 同 3。
    5. 同4。
    6. ...

    我想你明白了。 LogOn 操作应从身份验证中排除,否则用户将永远无法登录您的网站。

    由于您已全局应用 Authorize 属性,因此无法执行此操作。一种可能的方法是编写一个自定义的 AuthorizeAttribute,它将在全局范围内应用,并将此操作排除在身份验证之外。

    所以你可以写一个标记属性:

    public class AllowAnonymousAttribute : Attribute
    {
    }
    

    和一个全局自定义授权属性:

    public class MyAuthorizeAttribute : AuthorizeAttribute
    {
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            var exclude = ((AllowAnonymousAttribute[])filterContext.ActionDescriptor.GetCustomAttributes(typeof(AllowAnonymousAttribute), false)).Any();
            if (!exclude)
            {
                base.OnAuthorization(filterContext);
            }
        }
    }
    

    将被注册:

    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new MyAuthorizeAttribute());  
    }
    

    现在剩下的就是用我们的标记属性装饰您希望从身份验证中排除的控制器操作:

    public class AccountController : Controller
    {
        [AllowAnonymous]
        public ActionResult LogOn()
        {
            return View();
        }
    
        [AllowAnonymous]
        [HttpPost]
        public ActionResult LogOn(LogOnModel model, string returnUrl)
        {
            ...
        }
    }
    

    【讨论】:

    • 谢谢达林,这当然是非常清楚的,并有很大帮助。非常感谢。
    • @NewJoizey,你设法让它工作了吗?您对此主题还有其他问题吗?
    • 达林,感谢您的跟进。我在原始帖子中提到,我确实使用 MVC2 解决方法来完成这项工作,这暂时已经足够好了。我无法理解观察到的行为背后的“原因”,但您在“让我们看看这里发生了什么”下对此进行了解释。现在我理解了它,我可能会把它留给未来的重构来实现。
    猜你喜欢
    • 2014-06-30
    • 1970-01-01
    • 2013-01-25
    • 1970-01-01
    • 2017-02-18
    • 1970-01-01
    • 2013-03-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多