A data object containing information about FormsAuthenticationCookies, FormsAuthenticationTickets, and the IP address of the client that requested them. This is used for the stateful validation of incoming requests.
Inheritance: BaseAuthenticationTicket
        /// <summary>
        /// Detects the creation of a FormsAuthenticationCookie and FormsAuthenticationTicket
        /// during the processing of the current request (i.e., PostBack of Login page/action),
        /// records the state of both in a UserAuthenticationTicket, and adds it to the 
        /// Provider.
        /// 
        /// In the event that this request was already authenticated, it detects and handles 
        /// sliding expiration on the Provider.
        /// </summary>
        /// <param name="sender">The HttpApplication that sent the request</param>
        /// <param name="e">Not used</param>
        private static void OnEndRequest(object sender, EventArgs e)
        {
            // EnhancedSecurity.InterceptFormsAuthenticationCookie();
            FormsAuthenticationStatus status = EnhancedSecurity.GetFormsAuthStatus();

            HttpContext context = HttpContext.Current;
            HttpRequest request = context.Request;
            HttpResponse response = context.Response;

            /* TODO: Remove this once working */
            /*
            if (request.RawUrl.Contains("WebResource.axd"))
            {
                return;
            }
            */

            if (status == FormsAuthenticationStatus.NotFound || status == FormsAuthenticationStatus.Invalid)
            {
                RequestAnalysis preAnalyzer = RequestAnalyzer.RetrieveAnalysis(RequestLifecyclePhase.BeginRequest);
                RequestAnalysis postAnalyzer = RequestAnalyzer.AnalyzeRequest(response.Cookies[FormsAuthentication.FormsCookieName], RequestLifecyclePhase.EndRequest, true);

                if (preAnalyzer != null)
                {
                    ComparisonResult result = RequestAnalyzer.Compare(preAnalyzer, postAnalyzer);

                    if (result == ComparisonResult.UnauthenticatedRequest)
                    {
                        // Nothing to do
                    }
                    else if (result == ComparisonResult.AuthenticatedRequest)
                    {
                        // Nothing to do
                    }
                    else if (result == ComparisonResult.LoginRequest)
                    {
                        // Store the ticket on the server
                        string hash = UserAuthentication.CalculateFormsAuthTicketHash(postAnalyzer.FormsAuthenticationTicket);
                        string key = Guid.NewGuid().ToString();

                        UserAuthenticationTicket userAuthTicket = new UserAuthenticationTicket
                        {
                            Key = key,
                            Username = postAnalyzer.FormsAuthenticationTicket.Name,
                            HostAddress = request.UserHostAddress,
                            CookieDomain = postAnalyzer.FormsAuthenticationCookie.Domain,
                            CookiePath = postAnalyzer.FormsAuthenticationCookie.Path,
                            CookieSecure = postAnalyzer.FormsAuthenticationCookie.Secure,
                            TicketExpiration = postAnalyzer.FormsAuthenticationTicket.Expiration,
                            CookieName = postAnalyzer.FormsAuthenticationCookie.Name,
                            TicketIsPersistent = postAnalyzer.FormsAuthenticationTicket.IsPersistent,
                            TicketIssueDate = postAnalyzer.FormsAuthenticationTicket.IssueDate,
                            TicketUserData = postAnalyzer.FormsAuthenticationTicket.UserData,
                            TicketVersion = postAnalyzer.FormsAuthenticationTicket.Version,
                            TicketHash = hash
                        };

                        UserAuthentication.Provider.InsertTicket(userAuthTicket, postAnalyzer.FormsAuthenticationTicket.Expiration);

                        FormsAuthenticationTicket newFormsAuthTicket = UserAuthentication.CreateFormsAuthTicket(
                            postAnalyzer.FormsAuthenticationTicket.Name,
                            postAnalyzer.FormsAuthenticationCookie.Path,
                            hash + ";" + key,
                            postAnalyzer.FormsAuthenticationTicket.IssueDate,
                            postAnalyzer.FormsAuthenticationTicket.Expiration,
                            false
                        );

                        UserAuthentication.ClearAuthCookie();
                        UserAuthentication.SetAuthCookie(newFormsAuthTicket, true, true);
                    }
                    else if (result == ComparisonResult.LogoutRequest)
                    {
                        if (preAnalyzer.UserAuthenticationTicket != null)
                        {
                            UserAuthentication.Provider.RevokeTicket(preAnalyzer.UserAuthenticationTicket.Key);
                        }
                        UserAuthentication.ClearAuthCookie();

                        // Revoke the ticket on the server
                    }
                    else if (result == ComparisonResult.MaliciousRequest)
                    {
                        UserAuthentication.ClearAuthCookie();

                        // Hmm.. what to do
                        // System.Diagnostics.Debugger.Break();
                    }
                }
            }
            else if (status == FormsAuthenticationStatus.Valid)
            {
                // TODO: Handle sliding ticket expiration
                // UserAuthentication.Provider.UpdateTicketExpiration();
            }
        }
 internal void SetServerAuthenticationTicket(UserAuthenticationTicket userAuthenticationTicket)
 {
     _userAuthenticationTicket = userAuthenticationTicket;
 }
        /// <summary>
        /// Perform analysis of the UserAuthenticationTicket supplied
        /// </summary>
        /// <param name="contextInformation">Context information derived from the current request</param>
        /// <param name="cookieAnalysis">The result of the FormsAuthenticationCookie analysis</param>
        /// <param name="ticketAnalysis">The result of the FormsAuthenticationTicket analysis</param>
        /// <param name="userAuthenticationTicket">The UserAuthenticationTicket to inspect</param>
        /// <param name="enforceHostAddressValidation">Indicates whether to enforce that the ticket was provided from the same IP address for which it created</param>
        /// <returns>A UserAuthenticationTicketAnalysis object containing the results of the analysis</returns>
        public static UserAuthenticationTicketAnalysis AnalyzeServerAuthenticationTicket(ContextInformation contextInformation, FormsAuthenticationCookieAnalysis cookieAnalysis, FormsAuthenticationTicketAnalysis ticketAnalysis, UserAuthenticationTicket userAuthenticationTicket, bool enforceHostAddressValidation)
        {
            UserAuthenticationTicketAnalysis analysis = new UserAuthenticationTicketAnalysis();
            HttpCookie formsAuthCookie = cookieAnalysis.FormsAuthenticationCookie;
            FormsAuthenticationTicket formsAuthTicket = ticketAnalysis.FormsAuthenticationTicket;

            analysis.TicketExists = (userAuthenticationTicket != null);
            if (analysis.TicketExists)
            {
                analysis.UserAuthenticationTicket = userAuthenticationTicket;
                if (userAuthenticationTicket != null)
                {
                    analysis.CookieDomainMatch = (userAuthenticationTicket.CookieDomain == formsAuthCookie.Domain);
                    analysis.CookiePathMatch = (userAuthenticationTicket.CookiePath == formsAuthTicket.CookiePath && formsAuthTicket.CookiePath == formsAuthCookie.Path);
                    analysis.CookieSecureMatch = (userAuthenticationTicket.CookieSecure == formsAuthCookie.Secure);
                    /* analysis.ExpirationMatch = (DateTime.Compare(UserAuthenticationTicket.TicketExpiration, formsAuthTicket.Expiration) == 0 && DateTime.Compare(formsAuthTicket.Expiration, formsAuthCookie.Expires) == 0); */
                    analysis.CookieNameMatch = (userAuthenticationTicket.CookieName == formsAuthCookie.Name);
                    analysis.TicketPersistenceMatch = (userAuthenticationTicket.TicketIsPersistent == formsAuthTicket.IsPersistent);
                    analysis.TicketIssueDateMatch = (DateTime.Compare(userAuthenticationTicket.TicketIssueDate, formsAuthTicket.IssueDate) == 0);
                    analysis.TicketUsernameMatch = (userAuthenticationTicket.Username == formsAuthTicket.Name);
                    analysis.TicketVersionMatch = (userAuthenticationTicket.TicketVersion == formsAuthTicket.Version);
                    analysis.TicketHashMatch = (userAuthenticationTicket.TicketHash == ticketAnalysis.TicketHash);
                    analysis.HostAddressMatch = (userAuthenticationTicket.HostAddress == contextInformation.HostAddress);
                }

                analysis.IsValid =
                    analysis.CookieDomainMatch &&
                    analysis.CookiePathMatch &&
                    analysis.CookieSecureMatch &&
                    /* analysis.ExpirationMatch && */
                    analysis.CookieNameMatch &&
                    analysis.TicketPersistenceMatch &&
                    analysis.TicketIssueDateMatch &&
                    analysis.TicketUsernameMatch &&
                    analysis.TicketVersionMatch &&
                    analysis.TicketHashMatch &&
                    (!enforceHostAddressValidation || analysis.HostAddressMatch);

                if (!analysis.IsValid)
                {
                    analysis.IsMalicious =
                        !analysis.CookieDomainMatch ||
                        !analysis.CookiePathMatch ||
                        !analysis.CookieSecureMatch ||
                        /* !analysis.ExpirationMatch ||  */
                        !analysis.CookieNameMatch ||
                        !analysis.TicketPersistenceMatch ||
                        !analysis.TicketIssueDateMatch ||
                        !analysis.TicketUsernameMatch ||
                        !analysis.TicketVersionMatch ||
                        !analysis.TicketHashMatch ||
                        (enforceHostAddressValidation && !analysis.HostAddressMatch);
                }
            }
            else
            {
                analysis.IsValid = false;
                analysis.IsMalicious = false;
            }
            return analysis;
        }
    protected void TamperButton_Click(object sender, EventArgs e)
    {
        string formsAuthCookieValue = CookieValueServer.Text;
        FormsAuthenticationTicket newTicket = null;

        if (TamperFormsAuthenticationTicket.Checked)
        {
            newTicket = UserAuthentication.CreateFormsAuthTicket(
                TicketName.Text,
                TicketCookiePath.Text,
                TicketUserDataServer.Text,
                string.IsNullOrEmpty(TicketIssueDate.Text) ? (DateTime?)null : DateTime.Parse(TicketIssueDate.Text),
                string.IsNullOrEmpty(TicketExpiration.Text) ? (DateTime?)null : DateTime.Parse(TicketExpiration.Text),
                TicketIsPersistent.Checked
            );

            formsAuthCookieValue = FormsAuthentication.Encrypt(newTicket);
        }

        if (TamperFormsAuthenticationCookie.Checked)
        {
            UserAuthentication.ClearAuthCookie();

            HttpCookie newCookie = new HttpCookie(FormsAuthentication.FormsCookieName);
            newCookie.Domain = CookieDomain.Text;
            newCookie.Path = CookiePath.Text;
            newCookie.Secure = CookieSecure.Checked;
            newCookie.HttpOnly = true;

            DateTime newDate = DateTime.MinValue;
            if (!string.IsNullOrEmpty(CookieExpires.Text) && DateTime.TryParse(CookieExpires.Text, out newDate))
            {
                newCookie.Expires = newDate;
            }

            if (TamperFormsAuthenticationTicket.Checked)
            {
                newCookie.Value = formsAuthCookieValue;
            }
            else
            {
                newCookie.Value = CookieValueServer.Text;
            }

            Request.Cookies.Add(newCookie);  // Required for validation only
            Response.Cookies.Add(newCookie);
        }
        else if (TamperFormsAuthenticationTicket.Checked)
        {
            UserAuthentication.ClearAuthCookie();

            HttpCookie newCookie = new HttpCookie(FormsAuthentication.FormsCookieName, formsAuthCookieValue);
            newCookie.Path = FormsAuthentication.FormsCookiePath;
            newCookie.Secure = FormsAuthentication.RequireSSL;
            newCookie.HttpOnly = true;
            if (FormsAuthentication.CookieDomain != null)
            {
                newCookie.Domain = FormsAuthentication.CookieDomain;
            }
            if (TicketIsPersistent.Checked)
            {
                newCookie.Expires = newTicket.Expiration;
            }

            Request.Cookies.Add(newCookie);  // Required for validation only
            Response.Cookies.Add(newCookie);
        }

        if (TamperServerAuthenticationTicket.Checked)
        {
            string originalKey = Request["OriginalTicketKey"];
            string newKey = ServerKey.Text;

            UserAuthentication.Provider.RevokeTicket(originalKey);

            UserAuthenticationTicket serverAuthenticationTicket = new UserAuthenticationTicket();
            serverAuthenticationTicket.Key = ServerKey.Text;
            serverAuthenticationTicket.Username = ServerUsername.Text;
            serverAuthenticationTicket.HostAddress = ServerHostAddress.Text;
            serverAuthenticationTicket.CookieName = ServerCookieName.Text;
            serverAuthenticationTicket.CookieDomain = ServerCookieDomain.Text;
            serverAuthenticationTicket.CookiePath = ServerCookiePath.Text;
            serverAuthenticationTicket.CookieSecure = ServerCookieSecure.Checked;
            serverAuthenticationTicket.TicketIsPersistent = ServerTicketIsPersistent.Checked;
            serverAuthenticationTicket.TicketUserData = ServerTicketUserData.Text;
            serverAuthenticationTicket.TicketVersion = int.Parse(ServerTicketVersion.Text);
            serverAuthenticationTicket.TicketHash = ServerTicketHash.Text;

            DateTime ticketExpiration = DateTime.MinValue;
            DateTime ticketIssueDate = DateTime.MinValue;

            if (DateTime.TryParse(ServerTicketExpiration.Text, out ticketExpiration))
            {
                serverAuthenticationTicket.TicketExpiration = ticketExpiration;
            }

            if (DateTime.TryParse(ServerTicketIssueDate.Text, out ticketIssueDate))
            {
                serverAuthenticationTicket.TicketIssueDate = ticketIssueDate;
            }

            UserAuthentication.Provider.InsertTicket(serverAuthenticationTicket, ticketExpiration);
        }

        Response.Redirect(Request.RawUrl, false);
        // postAnalyzer = new FormsAuthenticationAnalyzer(Request.Cookies[FormsAuthentication.FormsCookieName], true);
        // BindFields();
        // ValidateFields();
    }