当`PostAuthenticateRequest`被执行时?

这是我的Global.asax.cs文件:

 public class MvcApplication : System.Web.HttpApplication { public static void RegisterRoutes(RouteCollection routes) { ... } protected void Application_Start() { this.PostAuthenticateRequest += new EventHandler(MvcApplication_PostAuthenticateRequest); } // This method never called by requests... protected void MvcApplication_PostAuthenticateRequest(object sender, EventArgs e) { HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName]; if (authCookie != null) { FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value); var identity = new GenericIdentity(authTicket.Name, "Forms"); var principal = new GenericPrincipal(identity, new string[] { }); Context.User = principal; } } } 

PostAuthenticateRequest执行时?

根据文件 :

安全模块已建立用户标识时发生。

在AuthenticateRequest事件发生后引发PostAuthenticateRequest事件。 订阅PostAuthenticateRequest事件的function可以访问PostAuthenticateRequest处理的任何数据。

这是ASP.NET页面生命周期 。

但是因为您的问题是用ASP.NET MVC标记的,所以我强烈建议您将其执行到自定义[Authorize]属性而不是使用此事件。 例:

 public class MyAuthorizeAttribute : AuthorizeAttribute { protected override bool AuthorizeCore(HttpContextBase httpContext) { var isAuthorized = base.AuthorizeCore(httpContext); if (isAuthorized) { var authCookie = httpContext.Request.Cookies[FormsAuthentication.FormsCookieName]; if (authCookie != null) { var authTicket = FormsAuthentication.Decrypt(authCookie.Value); var identity = new GenericIdentity(authTicket.Name, "Forms"); var principal = new GenericPrincipal(identity, new string[] { }); httpContext.User = principal; } } return isAuthorized; } } 

现在用[MyAuthorize]属性装饰你的控制器/动作:

 [MyAuthorize] public ActionResult Foo() { // if you got here the User property will be the custom // principal you injected in the authorize attribute ... } 

如果您将代码放在PostAuthenticateRequest上,则每个请求可能会多次命中,因为页面上引用的图像和样式表等每个资源都会触发此事件,因为它们被视为单独的请求。

如果你使用@ Darin的答案,当isAuthorized返回false时,AuthorizeAttribute将不会呈现操作,但人们可能无论如何都需要呈现它,即使它是一个公共页面(不受限制的访问)你可能想要显示“显示名称” “保存在authTicket的userData部分。

为此,我建议在ActionFilterAttribute(AuthenticationFilter)上加载authCookie:

 public class LoadCustomAuthTicket : ActionFilterAttribute, IAuthenticationFilter { public void OnAuthentication(AuthenticationContext filterContext) { if (!filterContext.Principal.Identity.IsAuthenticated) return; HttpCookie authCookie = filterContext.HttpContext.Request.Cookies[FormsAuthentication.FormsCookieName]; if (authCookie == null) return; FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value); var identity = new GenericIdentity(authTicket.Name, "Forms"); var principal = new GenericPrincipal(identity, new string[] { }); // Make sure the Principal's are in sync. see: https://www.hanselman.com/blog/SystemThreadingThreadCurrentPrincipalVsSystemWebHttpContextCurrentUserOrWhyFormsAuthenticationCanBeSubtle.aspx filterContext.Principal = filterContext.HttpContext.User = System.Threading.Thread.CurrentPrincipal = principal; } public void OnAuthenticationChallenge(AuthenticationChallengeContext filterContext) { //This method is responsible for validating the current principal and permitting the execution of the current action/request. //Here you should validate if the current principle is valid / permitted to invoke the current action. (However I would place this logic to an authorization filter) //filterContext.Result = new RedirectToRouteResult("CustomErrorPage",null); } } 

在global.asax.cs上

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

这样,您也不必使用该属性填充所有操作。