Asp.net mvc 3 全局授权不起作用-导致呈现空白页
我正在尝试为我的MVC3站点实现一个非常基本的登录方案。如果我理解正确,我应该能够实现一个全局设置,而不是将[Authorize]标记添加到每个控制器类中。为此,我在global.asax中添加了以下内容:Asp.net mvc 3 全局授权不起作用-导致呈现空白页,asp.net-mvc-3,login,global-asax,authorize-attribute,Asp.net Mvc 3,Login,Global Asax,Authorize Attribute,我正在尝试为我的MVC3站点实现一个非常基本的登录方案。如果我理解正确,我应该能够实现一个全局设置,而不是将[Authorize]标记添加到每个控制器类中。为此,我在global.asax中添加了以下内容: protected void Application_Start() { RegisterGlobalFilters(GlobalFilters.Filters); } public static void RegisterGlobalFilters(GlobalFilterCol
protected void Application_Start()
{
RegisterGlobalFilters(GlobalFilters.Filters);
}
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new AuthorizeAttribute());
}
在我的网络配置中,我补充道:
<authentication mode="Forms">
<forms loginUrl="~/Account/LogOn" timeout="2880" />
</authentication>
结果是生成的页面完全为空。查看url,mvc似乎正在按预期重定向到我的登录路径,但页面为空。如果我注释掉global.asax中的代码,并将[Authorize]标记直接放在每个控件中,它将按预期工作
作为一种解决方法,我实现了我读过的MVC2最佳实践,即创建一个BaseController:Controller类,向其中添加[Authorize]标记,然后将我所有控制器的固有性更改为inheret from BaseController而不是Controller
目前看来,这种方法已经足够有效了
但是为什么global.asax的实现不起作用呢?让我们看看这里发生了什么:
/
~/Account/LogOn
(按照web.config文件中的说明)进行身份验证~/Account/LogOn
(按照web.config文件中的说明)进行身份验证登录
操作应排除在身份验证之外,否则用户将永远无法登录到您的网站
由于您已全局应用了Authorize属性,因此无法执行此操作。一种可能的方法是编写一个自定义authorized属性,该属性将全局应用,并将此操作从身份验证中排除
因此,您可以编写一个标记属性:
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 class AccountController : Controller
{
[AllowAnonymous]
public ActionResult LogOn()
{
return View();
}
[AllowAnonymous]
[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl)
{
...
}
}
和全局自定义授权属性:
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 class AccountController : Controller
{
[AllowAnonymous]
public ActionResult LogOn()
{
return View();
}
[AllowAnonymous]
[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl)
{
...
}
}
将在以下地点登记:
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new MyAuthorizeAttribute());
}
现在,您只需使用标记属性来修饰要从身份验证中排除的控制器操作:
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 class AccountController : Controller
{
[AllowAnonymous]
public ActionResult LogOn()
{
return View();
}
[AllowAnonymous]
[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl)
{
...
}
}
让我们看看这里发生了什么:
/
~/Account/LogOn
(按照web.config文件中的说明)进行身份验证~/Account/LogOn
(按照web.config文件中的说明)进行身份验证登录
操作应排除在身份验证之外,否则用户将永远无法登录到您的网站
由于您已全局应用了Authorize属性,因此无法执行此操作。一种可能的方法是编写一个自定义authorized属性,该属性将全局应用,并将此操作从身份验证中排除
因此,您可以编写一个标记属性:
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 class AccountController : Controller
{
[AllowAnonymous]
public ActionResult LogOn()
{
return View();
}
[AllowAnonymous]
[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl)
{
...
}
}
和全局自定义授权属性:
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 class AccountController : Controller
{
[AllowAnonymous]
public ActionResult LogOn()
{
return View();
}
[AllowAnonymous]
[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl)
{
...
}
}
将在以下地点登记:
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new MyAuthorizeAttribute());
}
现在,您只需使用标记属性来修饰要从身份验证中排除的控制器操作:
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 class AccountController : Controller
{
[AllowAnonymous]
public ActionResult LogOn()
{
return View();
}
[AllowAnonymous]
[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl)
{
...
}
}
谢谢你,达林,这当然是非常清楚的安排,帮助很大。非常感谢。@NewJoizey,你设法让它工作了吗?关于这个问题,你还有其他问题吗?达林,谢谢你的跟进。我在最初的帖子中提到,我确实使用MVC2解决方案完成了这项工作,这在目前来说已经足够好了。我无法理解观察到的行为背后的“为什么”,但你在“让我们看看这里发生了什么”下解释了这一点。现在我明白了,我可能会把它留给未来的重构来实现。谢谢Darin,这当然是非常清楚的,而且非常有帮助。非常感谢。@NewJoizey,你设法让它工作了吗?关于这个问题,你还有其他问题吗?达林,谢谢你的跟进。我在最初的帖子中提到,我确实使用MVC2解决方案完成了这项工作,这在目前来说已经足够好了。我无法理解观察到的行为背后的“为什么”,但你在“让我们看看这里发生了什么”下解释了这一点。现在我明白了,我可能会把它留给未来的重构来实现。