0

我正在尝试为我的 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 实现不起作用呢?

4

1 回答 1

3

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

  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)
    {
        ...
    }
}
于 2012-07-18T14:50:06.170 回答