private void OnEnter(object source, EventArgs eventArgs) { HttpContext context = application.Context; this.OnAuthenticate(new FormsAuthenticationEventArgs(context)); CookielessHelperClass cookielessHelper = context.CookielessHelper; if (AuthenticationConfig.AccessingLoginPage(context, FormsAuthentication.LoginUrl)) { context.SetSkipAuthorizationNoDemand(true, false); cookielessHelper.RedirectWithDetectionIfRequired(null, FormsAuthentication.CookieMode); } if (!context.SkipAuthorization) { context.SetSkipAuthorizationNoDemand(AssemblyResourceLoader.IsValidWebResourceRequest(context), false); } }
分析代码,首先调用了OnAuthenticate方法,OnAuthenticate通过Cookie配置信息对每次的请求作Cookie更新,例如如果设置Cookie为可调过期(Slid),那么每次请求都会对cookie的过期时间更新。然后调用了AuthenticationConfig.AccessingLoginPage方法,判断是否正在请求配置的LoginUrl,如果是则直接跳过授权步骤。如果没有跳过授权步骤,检查当前请求是否为Web资源请求,如果是则直接跳过授权步骤。在EndRequest管道步骤上,我们注册了OnLeave方法,代码如下:
private void OnLeave(object source, EventArgs eventArgs) { HttpApplication application = (HttpApplication)source; HttpContext context = application.Context; ((context.Response.StatusCode == 0x191) && !context.Response.SuppressFormsAuthenticationRedirect) { rawUrl = context.Request.RawUrl; + FormsAuthentication.ReturnUrlVar + , StringComparison.Ordinal) == -+ FormsAuthentication.ReturnUrlVar + , StringComparison.Ordinal) == -1)) { strUrl = AuthenticationConfig.GetCompleteLoginUrl(context, FormsAuthentication.LoginUrl); CookielessHelperClass cookielessHelper = context.CookielessHelper; ) >= 0) { strUrl = FormsAuthentication.RemoveQueryStringVariableFromUrl(strUrl, FormsAuthentication.ReturnUrlVar); str3 = strUrl + + FormsAuthentication.ReturnUrlVar + + HttpUtility.UrlEncode(rawUrl, context.Request.ContentEncoding); } else { str3 = strUrl + + FormsAuthentication.ReturnUrlVar + + HttpUtility.UrlEncode(rawUrl, context.Request.ContentEncoding); } ); if ((index >= 0) && (index < (rawUrl.Length - 1))) { str3 = str3 + + rawUrl.Substring(index + 1); } cookielessHelper.SetCookieValue(, null); cookielessHelper.RedirectWithDetectionIfRequired(str3, FormsAuthentication.CookieMode); context.Response.Redirect(str3, false); } } }
5. DefaultAuthenticationModule
所在管道步骤:AuthenticateRequest。DefaultAuthenticationModule的Init把OnEnter方法注册到AuthenticateRequest管道步骤上。OnEnter代码如下:
private void OnEnter(object source, EventArgs eventArgs) { if (context.Response.StatusCode > 200) { if (context.Response.StatusCode == 0x191) { this.WriteErrorMessage(context); } application.CompleteRequest(); } else { if (context.User == null) { this.OnAuthenticate(new DefaultAuthenticationEventArgs(context)); if (context.Response.StatusCode > 200) { if (context.Response.StatusCode == 0x191) { this.WriteErrorMessage(context); } application.CompleteRequest(); return; } } if (context.User == null) { context.SetPrincipalNoDemand(new GenericPrincipal(new GenericIdentity(string.Empty, string.Empty), new string[0]), false); } Thread.CurrentPrincipal = context.User; } }
代码也比较简单,判断Response中的Status状态是等于401,是则写日志,直接结束本次请求。不是则设置当前线程的CurrentPrincipal为当前请求的用户。
6. RoleManagerModule所在管道步骤:AuthenticateRequest、EndRequest。RoleManagerModule的Init方法把OnEnter方法注册到AuthenticateRequest管道步骤上,把OnLeave方法注册到EndRequest。OnEnter方法代码如下: