我有一些定制的FormsAuthentication和一个定制的AuthorizeAttribute,在这里我手动维护cookie,但是我是在过滤器的上下文中这样做的。
我想要做的是把它移到最开始的入口点,在请求生命的最开始的时候,并且只做一次,而不依赖于一个属性来启动它。
但是,我不知道那会在哪里。MVC的页面生命周期与WebForms生命周期非常不同,因此它不像订阅WebForm的页面生命周期事件那样单调。
那么,在ASP.NET MVC中,HttpContext从哪里开始呢?
发布于 2015-03-19 14:20:33
随着对这个问题的深入研究,我偶然发现了Cephas优秀文章和ASP.NET MVC 5's生命周期的PDF。
PDF包含两个图像,清晰地描绘了MVC 5's生命周期的流程。第一个是10,000英尺的视角。第二张图片非常详细,太大了,无法在这里分享。
第一张图片:
在做了一些调查之后,我拼凑出了一些解决办法。以不同顺序执行的两个授权筛选器。
MVC过滤器有一个基于Eranga对这个问题的回答的操作顺序:https://stackoverflow.com/questions/6561883/in-what-order-are-filters-executed-in-asp-net-mvc
埃兰加写道:过滤器按以下顺序运行:
例如,授权筛选器首先运行,异常筛选器运行到最后。在每个筛选器类型中,order值指定运行顺序。在每个筛选器类型和顺序中,作用域枚举值指定筛选器的顺序。此枚举定义以下筛选器作用域值(按它们运行的顺序):
从MSDN提取
有了这些知识,我实现了第二个授权属性LoadAuthCookie
,它处理加载cookie,将当前用户的相关角色/权限数据提取到自定义IPrincipal和IIdentity中,并将当前HttpContext的用户分配给该IPrincipal。
LoadAuthCookie
属性仅在存在且不处理重定向或任何其他授权逻辑并在RegisterGlobalFilters
中注册的情况下加载cookie数据。
从Global.asax开始:
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
/* other global stuff */
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
/* other global stuff */
}
}
然后
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new LoadAuthCookie());
}
这不仅在以前注册了LoadAuthCookie
属性,而且比其他授权属性具有更高的操作顺序。
然后,我的另一个授权属性CustomAuthorize
可以在Controller/Action级别应用,并且总是在加载auth之后触发,访问自定义IPrincipal中的所有美好事物也是如此。
[CustomAuthorize(Role=Role.Admin)]
public class AdminController : ControllerBase
{
public ActionResult Index()
{
return View();
}
}
但是,这可能并不理想,自定义身份验证筛选器将是加载auth cookie的地方,而不是自定义授权筛选器。身份验证在授权之前进行。
发布于 2015-03-18 14:03:04
如果建议这样做,就不会有AuthorizeAttribute
,也不会是一个未密封的类。
即使你能处理它--但你不能--最糟糕的性能影响是每个HttpContext
占用了大量内存。检查会话字典中是否存在项是当前版本的ASP.NET的一滴水桶。
自我托管的NancyFX和ASP.NET MVC 6实际上解决了其中的一些挑战。如果您选择不在IIS上主机,则两者都不需要使用HttpContext。您可能会发现,NancyFX的管道和缺乏HTTPContext比您在ASP.NET中所做的更令人愉快和更有表现力。
https://softwareengineering.stackexchange.com/questions/276646
复制相似问题