private void OnEnter(object source, EventArgs eventArgs) { if (Roles.CacheRolesInCookie) { if (context.User.Identity.IsAuthenticated && (!Roles.CookieRequireSSL || context.Request.IsSecureConnection)) { HttpCookie cookie = context.Request.Cookies[Roles.CookieName]; if (cookie != null) { string encryptedTicket = cookie.Value; )) { cookie.Path = Roles.CookiePath; } cookie.Domain = Roles.Domain; context.SetPrincipalNoDemand(this.CreateRolePrincipalWithAssert(context.User.Identity, encryptedTicket)); } } else { if (context.Request.Cookies[Roles.CookieName] != null) { Roles.DeleteCookie(); } if (HttpRuntime.UseIntegratedPipeline) { context.DisableNotifications(RequestNotification.EndRequest, 0); } } } if (!(context.User is RolePrincipal)) { context.SetPrincipalNoDemand(this.CreateRolePrincipalWithAssert(context.User.Identity, null)); } HttpApplication.SetCurrentPrincipalWithAssert(context.User); }
如果设置了CacheRolesInCookie,并且身份已经通过认证了。接下来就从请求中获取Role的Cookie,并使用认证的身份创建角色安全体保存到上下文中;如果认证没通过,并且Cookie中有角色的Cookie,则删除角色Cookie。OnLeave代码如下:
private void OnLeave(object source, EventArgs eventArgs) { if (((Roles.Enabled && Roles.CacheRolesInCookie) && !context.Response.HeadersWritten) && (((context.User != null) && (context.User is RolePrincipal)) && context.User.Identity.IsAuthenticated)) { if (Roles.CookieRequireSSL && !context.Request.IsSecureConnection) { if (context.Request.Cookies[Roles.CookieName] != null) Roles.DeleteCookie(); } else { RolePrincipal user = (RolePrincipal)context.User; if (user.CachedListChanged && context.Request.Browser.Cookies) { string str = user.ToEncryptedTicket(); if (string.IsNullOrEmpty(str) || (str.Length > 0x1000)) Roles.DeleteCookie(); else { HttpCookie cookie = new HttpCookie(Roles.CookieName, str) { HttpOnly = true, Path = Roles.CookiePath, Domain = Roles.Domain }; if (Roles.CreatePersistentCookie) { cookie.Expires = user.ExpireDate; } cookie.Secure = Roles.CookieRequireSSL; context.Response.Cookies.Add(cookie); } } } } }
首先判断角色是否可用、是否把角色缓存存储在Cookie、上下文身份是否是角色安全体、是否通过认证,只有满足这些条件才执行下面的流程。满足条件后,如果Cookie需要SSL认证并且不是安全连接,则删除Cookie中的角色Cookie;否则,重新生成新的Cookie并返回到Response中。
7. UrlAuthorizationModule所在管道步骤:AuthorizeRequest。UrlAuthorizationModule的Init把OnEnter方法注册到AuthorizeRequest管道步骤上。OnEnter方法代码如下:
private void OnEnter(object source, EventArgs eventArgs) { AuthorizationSection authorization = RuntimeConfig.GetConfig(context).Authorization; if (!authorization.EveryoneAllowed && !authorization.IsUserAllowed(context.User, context.Request.RequestType)) { ReportUrlAuthorizationFailure(context, this); } else { if ((context.User == null) || !context.User.Identity.IsAuthenticated) { PerfCounters.IncrementCounter(AppPerfCounter.ANONYMOUS_REQUESTS); } WebBaseEvent.RaiseSystemEvent(this, 0xfa3); } }
首先从配置中获取授权节点,如果当前用户被限制,则调用ReportUrlAuthorizationFailure方法记录Url授权报告并终止本次请求;如果授权成功,执行WebSuccessAuditEvent系统事件。
8. FileAuthorizationModule所在管道步骤:AuthorizeRequest。FileAuthorizationModule的Init把OnEnter方法注册到AuthorizeRequest管道步骤上。OnEnter代码如下:
private void OnEnter(object source, EventArgs eventArgs) { if (!IsUserAllowedToFile(context, null)) { context.Response.SetStatusCode(0x191, 3); this.WriteErrorMessage(context); application.CompleteRequest(); } }