Inheritance: System.MarshalByRefObject, IIdentity
        /// <summary>
        /// Handles the AuthenticateRequest event of the context control.
        /// </summary>
        /// <param name="sender">
        /// The source of the event.
        /// </param>
        /// <param name="e">
        /// The <see cref="System.EventArgs"/> instance containing the event data.
        /// </param>
        private static void ContextAuthenticateRequest(object sender, EventArgs e)
        {
            // default to an empty/unauthenticated user to assign to context.User.
            CustomIdentity identity = new CustomIdentity(string.Empty, false);
            CustomPrincipal principal = new CustomPrincipal(identity);

            var context = ((HttpApplication)sender).Context;

            // FormsAuthCookieName is a custom cookie name based on the current instance.
            HttpCookie authCookie = context.Request.Cookies[FormsAuthCookieName];
            if (authCookie != null)
            {
                Blog blog = Blog.CurrentInstance;

                FormsAuthenticationTicket authTicket = null;
                try
                {
                    authTicket = FormsAuthentication.Decrypt(authCookie.Value);
                }
                catch (Exception ex)
                {
                    context.Request.Cookies.Remove(FormsAuthCookieName);
                    authTicket = null;

                    Utils.Log("Failed to decrypt the FormsAuthentication cookie.", ex);
                }

                if (authTicket != null)
                {
                    identity = new CustomIdentity(authTicket.Name, true);

                    if (!string.IsNullOrWhiteSpace(authTicket.UserData))
                    {
                        int delimiter = authTicket.UserData.IndexOf(AUTH_TKT_USERDATA_DELIMITER);
                        if (delimiter != -1)
                        {
                            // for extra security, make sure the data in UserData contains the SecurityValidationKey
                            // and current blog instance.  the current blog instance check would prevent a cookie name
                            // change for a forms auth cookie encrypted in the same application (different blog) as
                            // being valid for this blog instance.

                            string securityValidationKey = authTicket.UserData.Substring(0, delimiter).Trim();
                            string blogId = authTicket.UserData.Substring(delimiter + AUTH_TKT_USERDATA_DELIMITER.Length).Trim();

                            if (securityValidationKey.Equals(SecurityValidationKey, StringComparison.OrdinalIgnoreCase) &&
                                blogId.Equals(Blog.CurrentInstance.Id.ToString(), StringComparison.OrdinalIgnoreCase))
                            {
                                principal = new CustomPrincipal(identity);
                            }
                        }
                    }
                    else if (BlogConfig.SingleSignOn)
                    {
                        principal = new CustomPrincipal(identity);
                    }
                }
            }
            context.User = principal;
        }
        /// <summary>
        /// Impersonates a user for the duration of the HTTP request.
        /// </summary>
        /// <param name="username">The username</param>
        /// <param name="password">The password</param>
        /// <returns>True if the credentials are correct and impersonation succeeds</returns>
        public static bool ImpersonateUser(string username, string password)
        {
            if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password))
                return false;

            CustomIdentity identity = new CustomIdentity(username, password);
            if (!identity.IsAuthenticated) { return false; }

            CustomPrincipal principal = new CustomPrincipal(identity);

            // Make the custom principal be the user for the rest of this request.
            HttpContext.Current.User = principal;

            return true;
        }
        /// <summary>
        /// Handles the AuthenticateRequest event of the context control.
        /// </summary>
        /// <param name="sender">
        /// The source of the event.
        /// </param>
        /// <param name="e">
        /// The <see cref="System.EventArgs"/> instance containing the event data.
        /// </param>
        private static void ContextAuthenticateRequest(object sender, EventArgs e)
        {
            var context = ((HttpApplication)sender).Context;

            // FormsAuthCookieName is a custom cookie name based on the current instance.
            HttpCookie authCookie = context.Request.Cookies[FormsAuthCookieName];
            if (authCookie != null)
            {
                Blog blog = Blog.CurrentInstance;

                FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);

                // for extra security, make sure the UserData matches the current blog instance.
                // this would prevent a cookie name change for a forms auth cookie encrypted in
                // the same application (different blog) as being valid for this blog instance.
                if (authTicket != null && !string.IsNullOrWhiteSpace(authTicket.UserData) && authTicket.UserData.Equals(Blog.CurrentInstance.Id.ToString(), StringComparison.OrdinalIgnoreCase))
                {
                    CustomIdentity identity = new CustomIdentity(authTicket.Name, true);
                    CustomPrincipal principal = new CustomPrincipal(identity);

                    context.User = principal;
                    return;
                }
            }

            // need to create an empty/unauthenticated user to assign to context.User.
            CustomIdentity unauthIdentity = new CustomIdentity(string.Empty, false);
            CustomPrincipal unauthPrincipal = new CustomPrincipal(unauthIdentity);
            context.User = unauthPrincipal;
        }