示例#1
0
        public static FormsAuthenticationTicket RenewTicketIfOld(FormsAuthenticationTicket tOld)
        {
            if (tOld == null)
            {
                return(null);
            }

            DateTime utcNow    = DateTime.UtcNow;
            TimeSpan ticketAge = utcNow - tOld.IssueDateUtc;
            TimeSpan ticketRemainingLifetime = tOld.ExpirationUtc - utcNow;

            if (ticketRemainingLifetime > ticketAge)
            {
                return(tOld); // no need to renew
            }
            // The original ticket may have had a custom-specified lifetime separate from
            // the default timeout specified in config. We should honor that original
            // lifetime when renewing the ticket.
            TimeSpan originalTicketTotalLifetime = tOld.ExpirationUtc - tOld.IssueDateUtc;
            DateTime newExpirationUtc            = utcNow + originalTicketTotalLifetime;

            FormsAuthenticationTicket ticket = FormsAuthenticationTicket.FromUtc(
                tOld.Version /* version */,
                tOld.Name /* name */,
                utcNow /* issueDateUtc */,
                newExpirationUtc /* expirationUtc */,
                tOld.IsPersistent /* isPersistent */,
                tOld.UserData /* userData */,
                tOld.CookiePath /* cookiePath */);

            return(ticket);
        }
示例#2
0
        private static HttpCookie GetAuthCookie(String userName, bool createPersistentCookie, String strCookiePath, bool hexEncodedTicket)
        {
            Initialize();
            if (userName == null)
            {
                userName = String.Empty;
            }

            if (strCookiePath == null || strCookiePath.Length < 1)
            {
                strCookiePath = FormsCookiePath;
            }

            DateTime issueDateUtc  = DateTime.UtcNow;
            DateTime expirationUtc = issueDateUtc.AddMinutes(_Timeout);

            FormsAuthenticationTicket ticket = FormsAuthenticationTicket.FromUtc(
                2,                      // version
                userName,               // User-Name
                issueDateUtc,           // Issue-Date
                expirationUtc,          // Expiration
                createPersistentCookie, // IsPersistent
                String.Empty,           // User-Data
                strCookiePath           // Cookie Path
                );

            String strTicket = Encrypt(ticket, hexEncodedTicket);

            if (strTicket == null || strTicket.Length < 1)
            {
                throw new HttpException(
                          SR.GetString(SR.Unable_to_encrypt_cookie_ticket));
            }


            HttpCookie cookie = new HttpCookie(FormsCookieName, strTicket);

            cookie.HttpOnly = true;
            cookie.Path     = strCookiePath;
            cookie.Secure   = _RequireSSL;
            if (_CookieDomain != null)
            {
                cookie.Domain = _CookieDomain;
            }
            if (ticket.IsPersistent)
            {
                cookie.Expires = ticket.Expiration;
            }
            cookie.SameSite = _cookieSameSite;
            return(cookie);
        }
示例#3
0
        public static FormsAuthenticationTicket RenewTicketIfOld(FormsAuthenticationTicket tOld)
        {
            if (tOld == null)
            {
                return(null);
            }
            DateTime utcNow = DateTime.UtcNow;
            TimeSpan span   = (TimeSpan)(utcNow - tOld.IssueDateUtc);
            TimeSpan span2  = (TimeSpan)(tOld.ExpirationUtc - utcNow);

            if (span2 > span)
            {
                return(tOld);
            }
            TimeSpan span3         = (TimeSpan)(tOld.ExpirationUtc - tOld.IssueDateUtc);
            DateTime expirationUtc = utcNow + span3;

            return(FormsAuthenticationTicket.FromUtc(tOld.Version, tOld.Name, utcNow, expirationUtc, tOld.IsPersistent, tOld.UserData, tOld.CookiePath));
        }
示例#4
0
        private static HttpCookie GetAuthCookie(string userName, bool createPersistentCookie, string strCookiePath, bool hexEncodedTicket)
        {
            Initialize();
            if (userName == null)
            {
                userName = string.Empty;
            }
            if ((strCookiePath == null) || (strCookiePath.Length < 1))
            {
                strCookiePath = FormsCookiePath;
            }
            DateTime utcNow                  = DateTime.UtcNow;
            DateTime expirationUtc           = utcNow.AddMinutes((double)_Timeout);
            FormsAuthenticationTicket ticket = FormsAuthenticationTicket.FromUtc(2, userName, utcNow, expirationUtc, createPersistentCookie, string.Empty, strCookiePath);
            string str = Encrypt(ticket, hexEncodedTicket);

            if ((str == null) || (str.Length < 1))
            {
                throw new HttpException(System.Web.SR.GetString("Unable_to_encrypt_cookie_ticket"));
            }
            HttpCookie cookie = new HttpCookie(FormsCookieName, str)
            {
                HttpOnly = true,
                Path     = strCookiePath,
                Secure   = _RequireSSL
            };

            if (_CookieDomain != null)
            {
                cookie.Domain = _CookieDomain;
            }
            if (ticket.IsPersistent)
            {
                cookie.Expires = ticket.Expiration;
            }
            return(cookie);
        }
示例#5
0
        ////////////////////////////////////////////////////////////
        // OnAuthenticate: Forms Authentication modules can override
        //             this method to create a Forms IPrincipal object from
        //             a WindowsIdentity
        private void OnAuthenticate(FormsAuthenticationEventArgs e)
        {
            HttpCookie cookie = null;

            ////////////////////////////////////////////////////////////
            // Step 1: If there are event handlers, invoke the handlers
            if (_eventHandler != null)
            {
                _eventHandler(this, e);
            }

            ////////////////////////////////////////////////////////////
            // Step 2: Check if the event handler created a user-object
            if (e.Context.User != null)
            {
                // do nothing because someone else authenticated
                return;
            }

            if (e.User != null)
            {
                // the event handler created a user
                e.Context.SetPrincipalNoDemand(e.User);
                return;
            }

            ////////////////////////////////////////////////////////////
            // Step 3: Extract the cookie and create a ticket from it
            bool cookielessTicket            = false;
            FormsAuthenticationTicket ticket = ExtractTicketFromCookie(e.Context, FormsAuthentication.FormsCookieName, out cookielessTicket);

            ////////////////////////////////////////////////////////////
            // Step 4: See if the ticket was created: No => exit immediately
            if (ticket == null || ticket.Expired)
            {
                return;
            }

            ////////////////////////////////////////////////////////////
            // Step 5: Renew the ticket
            FormsAuthenticationTicket ticket2 = ticket;

            if (FormsAuthentication.SlidingExpiration)
            {
                ticket2 = FormsAuthentication.RenewTicketIfOld(ticket);
            }

            ////////////////////////////////////////////////////////////
            // Step 6: Create a user object for the ticket
            e.Context.SetPrincipalNoDemand(new GenericPrincipal(new FormsIdentity(ticket2), new String[0]));

            ////////////////////////////////////////////////////////////
            // Step 7: Browser does not send us the correct cookie-path
            //         Update the cookie to show the correct path
            if (!cookielessTicket && !ticket2.CookiePath.Equals("/"))
            {
                cookie = e.Context.Request.Cookies[FormsAuthentication.FormsCookieName];
                if (cookie != null)
                {
                    cookie.Path = ticket2.CookiePath;
                }
            }

            ////////////////////////////////////////////////////////////
            // Step 8: If the ticket was renewed, save the ticket in the cookie
            if (ticket2 != ticket)
            {
                if (cookielessTicket && ticket2.CookiePath != "/" && ticket2.CookiePath.Length > 1)
                {
                    FormsAuthenticationTicket tempTicket = FormsAuthenticationTicket.FromUtc(ticket2.Version, ticket2.Name, ticket2.IssueDateUtc,
                                                                                             ticket2.ExpirationUtc, ticket2.IsPersistent, ticket2.UserData,
                                                                                             "/");
                    ticket2 = tempTicket;
                }
                String strEnc = FormsAuthentication.Encrypt(ticket2, !cookielessTicket);

                if (cookielessTicket)
                {
                    e.Context.CookielessHelper.SetCookieValue('F', strEnc);
                    e.Context.Response.Redirect(e.Context.Request.RawUrl);
                }
                else
                {
                    if (cookie != null)
                    {
                        cookie = e.Context.Request.Cookies[FormsAuthentication.FormsCookieName];
                    }

                    if (cookie == null)
                    {
                        cookie      = new HttpCookie(FormsAuthentication.FormsCookieName, strEnc);
                        cookie.Path = ticket2.CookiePath;
                    }

                    if (ticket2.IsPersistent)
                    {
                        cookie.Expires = ticket2.Expiration;
                    }
                    cookie.Value    = strEnc;
                    cookie.Secure   = FormsAuthentication.RequireSSL;
                    cookie.HttpOnly = true;
                    if (FormsAuthentication.CookieDomain != null)
                    {
                        cookie.Domain = FormsAuthentication.CookieDomain;
                    }
                    e.Context.Response.Cookies.Remove(cookie.Name);
                    e.Context.Response.Cookies.Add(cookie);
                }
            }
        }
示例#6
0
        ////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////
        // Private method for decrypting a cookie
        private static FormsAuthenticationTicket ExtractTicketFromCookie(HttpContext context, String name, out bool cookielessTicket)
        {
            FormsAuthenticationTicket ticket = null;
            string encValue      = null;
            bool   ticketExpired = false;
            bool   badTicket     = false;

            try {
                try {
                    ////////////////////////////////////////////////////////////
                    // Step 0: Check if we should use cookieless
                    cookielessTicket = CookielessHelperClass.UseCookieless(context, false, FormsAuthentication.CookieMode);

                    ////////////////////////////////////////////////////////////
                    // Step 1: Check URI/cookie for ticket
                    if (cookielessTicket)
                    {
                        encValue = context.CookielessHelper.GetCookieValue('F');
                    }
                    else
                    {
                        HttpCookie cookie = context.Request.Cookies[name];
                        if (cookie != null)
                        {
                            encValue = cookie.Value;
                        }
                    }

                    ////////////////////////////////////////////////////////////
                    // Step 2: Decrypt encrypted ticket
                    if (encValue != null && encValue.Length > 1)
                    {
                        try {
                            ticket = FormsAuthentication.Decrypt(encValue);
                        } catch {
                            if (cookielessTicket)
                            {
                                context.CookielessHelper.SetCookieValue('F', null);
                            }
                            else
                            {
                                context.Request.Cookies.Remove(name);
                            }
                            badTicket = true;
                            //throw;
                        }

                        if (ticket == null)
                        {
                            badTicket = true;
                        }

                        if (ticket != null && !ticket.Expired)
                        {
                            if (cookielessTicket || !FormsAuthentication.RequireSSL || context.Request.IsSecureConnection) // Make sure it is NOT a secure cookie over an in-secure connection
                            {
                                return(ticket);                                                                            // Found valid ticket
                            }
                        }

                        if (ticket != null && ticket.Expired)
                        {
                            ticketExpired = true;
                        }

                        // Step 2b: Remove expired/bad ticket
                        ticket = null;
                        if (cookielessTicket)
                        {
                            context.CookielessHelper.SetCookieValue('F', null);
                        }
                        else
                        {
                            context.Request.Cookies.Remove(name);
                        }
                    }


                    ////////////////////////////////////////////////////////////
                    // Step 3: Look in QueryString
                    if (FormsAuthentication.EnableCrossAppRedirects)
                    {
                        encValue = context.Request.QueryString[name];
                        if (encValue != null && encValue.Length > 1)
                        {
                            if (!cookielessTicket && FormsAuthentication.CookieMode == HttpCookieMode.AutoDetect)
                            {
                                cookielessTicket = CookielessHelperClass.UseCookieless(context, true, FormsAuthentication.CookieMode); // find out for sure
                            }
                            try {
                                ticket = FormsAuthentication.Decrypt(encValue);
                            } catch {
                                badTicket = true;
                                //throw;
                            }

                            if (ticket == null)
                            {
                                badTicket = true;
                            }
                        }

                        // Step 3b: Look elsewhere in the request (i.e. posted body)
                        if (ticket == null || ticket.Expired)
                        {
                            encValue = context.Request.Form[name];
                            if (encValue != null && encValue.Length > 1)
                            {
                                if (!cookielessTicket && FormsAuthentication.CookieMode == HttpCookieMode.AutoDetect)
                                {
                                    cookielessTicket = CookielessHelperClass.UseCookieless(context, true, FormsAuthentication.CookieMode); // find out for sure
                                }
                                try {
                                    ticket = FormsAuthentication.Decrypt(encValue);
                                } catch {
                                    badTicket = true;
                                    //throw;
                                }

                                if (ticket == null)
                                {
                                    badTicket = true;
                                }
                            }
                        }
                    }

                    if (ticket == null || ticket.Expired)
                    {
                        if (ticket != null && ticket.Expired)
                        {
                            ticketExpired = true;
                        }

                        return(null); // not found! Exit with null
                    }

                    if (FormsAuthentication.RequireSSL && !context.Request.IsSecureConnection) // Bad scenario: valid ticket over non-SSL
                    {
                        throw new HttpException(SR.GetString(SR.Connection_not_secure_creating_secure_cookie));
                    }

                    ////////////////////////////////////////////////////////////
                    // Step 4: Create the cookie/URI value
                    if (cookielessTicket)
                    {
                        if (ticket.CookiePath != "/")
                        {
                            FormsAuthenticationTicket tempTicket = FormsAuthenticationTicket.FromUtc(ticket.Version, ticket.Name, ticket.IssueDateUtc,
                                                                                                     ticket.ExpirationUtc, ticket.IsPersistent, ticket.UserData,
                                                                                                     "/");
                            ticket   = tempTicket;
                            encValue = FormsAuthentication.Encrypt(ticket);
                        }
                        context.CookielessHelper.SetCookieValue('F', encValue);
                        string strUrl = FormsAuthentication.RemoveQueryStringVariableFromUrl(context.Request.RawUrl, name);
                        context.Response.Redirect(strUrl);
                    }
                    else
                    {
                        HttpCookie cookie = new HttpCookie(name, encValue);
                        cookie.HttpOnly = true;
                        cookie.Path     = ticket.CookiePath;
                        if (ticket.IsPersistent)
                        {
                            cookie.Expires = ticket.Expiration;
                        }
                        cookie.Secure = FormsAuthentication.RequireSSL;
                        if (FormsAuthentication.CookieDomain != null)
                        {
                            cookie.Domain = FormsAuthentication.CookieDomain;
                        }
                        context.Response.Cookies.Remove(cookie.Name);
                        context.Response.Cookies.Add(cookie);
                    }

                    return(ticket);
                } finally {
                    if (badTicket)
                    {
                        WebBaseEvent.RaiseSystemEvent(null, WebEventCodes.AuditFormsAuthenticationFailure,
                                                      WebEventCodes.InvalidTicketFailure);
                    }
                    else if (ticketExpired)
                    {
                        WebBaseEvent.RaiseSystemEvent(null, WebEventCodes.AuditFormsAuthenticationFailure,
                                                      WebEventCodes.ExpiredTicketFailure);
                    }
                }
            } catch {
                throw;
            }
        }
        public static FormsAuthenticationTicket Deserialize(byte[] serializedTicket, int serializedTicketLength)
        {
            FormsAuthenticationTicket ticket;

            try
            {
                using (MemoryStream stream = new MemoryStream(serializedTicket))
                {
                    using (SerializingBinaryReader reader = new SerializingBinaryReader(stream))
                    {
                        int      num2;
                        DateTime time;
                        DateTime time2;
                        bool     flag;
                        string   str;
                        if (reader.ReadByte() == 1)
                        {
                            num2 = reader.ReadByte();
                            long ticks = reader.ReadInt64();
                            time = new DateTime(ticks, DateTimeKind.Utc);
                            time.ToLocalTime();
                            if (reader.ReadByte() != 0xfe)
                            {
                                return(null);
                            }
                            long num5 = reader.ReadInt64();
                            time2 = new DateTime(num5, DateTimeKind.Utc);
                            time2.ToLocalTime();
                            switch (reader.ReadByte())
                            {
                            case 0:
                                flag = false;
                                goto Label_00A1;

                            case 1:
                                flag = true;
                                goto Label_00A1;
                            }
                        }
                        return(null);

Label_00A1:
                        str = reader.ReadBinaryString();
                        string userData   = reader.ReadBinaryString();
                        string cookiePath = reader.ReadBinaryString();
                        if (reader.ReadByte() != 0xff)
                        {
                            return(null);
                        }
                        if (stream.Position != serializedTicketLength)
                        {
                            return(null);
                        }
                        ticket = FormsAuthenticationTicket.FromUtc(num2, str, time, time2, flag, userData, cookiePath);
                    }
                }
            }
            catch
            {
                ticket = null;
            }
            return(ticket);
        }
示例#8
0
        private static FormsAuthenticationTicket ExtractTicketFromCookie(HttpContext context, string name, out bool cookielessTicket)
        {
            FormsAuthenticationTicket ticket = null;
            string encryptedTicket           = null;
            FormsAuthenticationTicket ticket2;
            bool flag  = false;
            bool flag2 = false;

            try
            {
                try
                {
                    cookielessTicket = CookielessHelperClass.UseCookieless(context, false, FormsAuthentication.CookieMode);
                    if (cookielessTicket)
                    {
                        encryptedTicket = context.CookielessHelper.GetCookieValue('F');
                    }
                    else
                    {
                        HttpCookie cookie = context.Request.Cookies[name];
                        if (cookie != null)
                        {
                            encryptedTicket = cookie.Value;
                        }
                    }
                    if ((encryptedTicket != null) && (encryptedTicket.Length > 1))
                    {
                        try
                        {
                            ticket = FormsAuthentication.Decrypt(encryptedTicket);
                        }
                        catch
                        {
                            if (cookielessTicket)
                            {
                                context.CookielessHelper.SetCookieValue('F', null);
                            }
                            else
                            {
                                context.Request.Cookies.Remove(name);
                            }
                            flag2 = true;
                        }
                        if (ticket == null)
                        {
                            flag2 = true;
                        }
                        if (((ticket != null) && !ticket.Expired) && ((cookielessTicket || !FormsAuthentication.RequireSSL) || context.Request.IsSecureConnection))
                        {
                            return(ticket);
                        }
                        if ((ticket != null) && ticket.Expired)
                        {
                            flag = true;
                        }
                        ticket = null;
                        if (cookielessTicket)
                        {
                            context.CookielessHelper.SetCookieValue('F', null);
                        }
                        else
                        {
                            context.Request.Cookies.Remove(name);
                        }
                    }
                    if (FormsAuthentication.EnableCrossAppRedirects)
                    {
                        encryptedTicket = context.Request.QueryString[name];
                        if ((encryptedTicket != null) && (encryptedTicket.Length > 1))
                        {
                            if (!cookielessTicket && (FormsAuthentication.CookieMode == HttpCookieMode.AutoDetect))
                            {
                                cookielessTicket = CookielessHelperClass.UseCookieless(context, true, FormsAuthentication.CookieMode);
                            }
                            try
                            {
                                ticket = FormsAuthentication.Decrypt(encryptedTicket);
                            }
                            catch
                            {
                                flag2 = true;
                            }
                            if (ticket == null)
                            {
                                flag2 = true;
                            }
                        }
                        if ((ticket == null) || ticket.Expired)
                        {
                            encryptedTicket = context.Request.Form[name];
                            if ((encryptedTicket != null) && (encryptedTicket.Length > 1))
                            {
                                if (!cookielessTicket && (FormsAuthentication.CookieMode == HttpCookieMode.AutoDetect))
                                {
                                    cookielessTicket = CookielessHelperClass.UseCookieless(context, true, FormsAuthentication.CookieMode);
                                }
                                try
                                {
                                    ticket = FormsAuthentication.Decrypt(encryptedTicket);
                                }
                                catch
                                {
                                    flag2 = true;
                                }
                                if (ticket == null)
                                {
                                    flag2 = true;
                                }
                            }
                        }
                    }
                    if ((ticket == null) || ticket.Expired)
                    {
                        if ((ticket != null) && ticket.Expired)
                        {
                            flag = true;
                        }
                        return(null);
                    }
                    if (FormsAuthentication.RequireSSL && !context.Request.IsSecureConnection)
                    {
                        throw new HttpException(System.Web.SR.GetString("Connection_not_secure_creating_secure_cookie"));
                    }
                    if (cookielessTicket)
                    {
                        if (ticket.CookiePath != "/")
                        {
                            ticket          = FormsAuthenticationTicket.FromUtc(ticket.Version, ticket.Name, ticket.IssueDateUtc, ticket.ExpirationUtc, ticket.IsPersistent, ticket.UserData, "/");
                            encryptedTicket = FormsAuthentication.Encrypt(ticket);
                        }
                        context.CookielessHelper.SetCookieValue('F', encryptedTicket);
                        string url = FormsAuthentication.RemoveQueryStringVariableFromUrl(context.Request.RawUrl, name);
                        context.Response.Redirect(url);
                    }
                    else
                    {
                        HttpCookie cookie2 = new HttpCookie(name, encryptedTicket)
                        {
                            HttpOnly = true,
                            Path     = ticket.CookiePath
                        };
                        if (ticket.IsPersistent)
                        {
                            cookie2.Expires = ticket.Expiration;
                        }
                        cookie2.Secure = FormsAuthentication.RequireSSL;
                        if (FormsAuthentication.CookieDomain != null)
                        {
                            cookie2.Domain = FormsAuthentication.CookieDomain;
                        }
                        context.Response.Cookies.Remove(cookie2.Name);
                        context.Response.Cookies.Add(cookie2);
                    }
                    ticket2 = ticket;
                }
                finally
                {
                    if (flag2)
                    {
                        WebBaseEvent.RaiseSystemEvent(null, 0xfa5, 0xc419);
                    }
                    else if (flag)
                    {
                        WebBaseEvent.RaiseSystemEvent(null, 0xfa5, 0xc41a);
                    }
                }
            }
            catch
            {
                throw;
            }
            return(ticket2);
        }
示例#9
0
        private void OnAuthenticate(FormsAuthenticationEventArgs e)
        {
            HttpCookie cookie = null;

            if (this._eventHandler != null)
            {
                this._eventHandler(this, e);
            }
            if (e.Context.User == null)
            {
                if (e.User != null)
                {
                    e.Context.SetPrincipalNoDemand(e.User);
                }
                else
                {
                    bool cookielessTicket          = false;
                    FormsAuthenticationTicket tOld = ExtractTicketFromCookie(e.Context, FormsAuthentication.FormsCookieName, out cookielessTicket);
                    if ((tOld != null) && !tOld.Expired)
                    {
                        FormsAuthenticationTicket ticket = tOld;
                        if (FormsAuthentication.SlidingExpiration)
                        {
                            ticket = FormsAuthentication.RenewTicketIfOld(tOld);
                        }
                        e.Context.SetPrincipalNoDemand(new GenericPrincipal(new FormsIdentity(ticket), new string[0]));
                        if (!cookielessTicket && !ticket.CookiePath.Equals("/"))
                        {
                            cookie = e.Context.Request.Cookies[FormsAuthentication.FormsCookieName];
                            if (cookie != null)
                            {
                                cookie.Path = ticket.CookiePath;
                            }
                        }
                        if (ticket != tOld)
                        {
                            if ((cookielessTicket && (ticket.CookiePath != "/")) && (ticket.CookiePath.Length > 1))
                            {
                                ticket = FormsAuthenticationTicket.FromUtc(ticket.Version, ticket.Name, ticket.IssueDateUtc, ticket.ExpirationUtc, ticket.IsPersistent, ticket.UserData, "/");
                            }
                            string cookieValue = FormsAuthentication.Encrypt(ticket);
                            if (cookielessTicket)
                            {
                                e.Context.CookielessHelper.SetCookieValue('F', cookieValue);
                                e.Context.Response.Redirect(e.Context.Request.RawUrl);
                            }
                            else
                            {
                                if (cookie != null)
                                {
                                    cookie = e.Context.Request.Cookies[FormsAuthentication.FormsCookieName];
                                }
                                if (cookie == null)
                                {
                                    cookie = new HttpCookie(FormsAuthentication.FormsCookieName, cookieValue)
                                    {
                                        Path = ticket.CookiePath
                                    };
                                }
                                if (ticket.IsPersistent)
                                {
                                    cookie.Expires = ticket.Expiration;
                                }
                                cookie.Value    = cookieValue;
                                cookie.Secure   = FormsAuthentication.RequireSSL;
                                cookie.HttpOnly = true;
                                if (FormsAuthentication.CookieDomain != null)
                                {
                                    cookie.Domain = FormsAuthentication.CookieDomain;
                                }
                                e.Context.Response.Cookies.Remove(cookie.Name);
                                e.Context.Response.Cookies.Add(cookie);
                            }
                        }
                    }
                }
            }
        }
示例#10
0
        // Resurrects a FormsAuthenticationTicket from its serialized blob representation.
        // The input blob must be unsigned and unencrypted. This function returns null if
        // the serialized ticket format is invalid. The caller must also verify that the
        // ticket is still valid, as this method doesn't check expiration.
        public static FormsAuthenticationTicket Deserialize(byte[] serializedTicket, int serializedTicketLength)
        {
            try {
                using (MemoryStream ticketBlobStream = new MemoryStream(serializedTicket)) {
                    using (SerializingBinaryReader ticketReader = new SerializingBinaryReader(ticketBlobStream)) {
                        // Step 1: Read the serialized format version number from the stream.
                        // Currently the only supported format is 0x01.
                        // LENGTH: 1 byte
                        byte serializedFormatVersion = ticketReader.ReadByte();
                        if (serializedFormatVersion != CURRENT_TICKET_SERIALIZED_VERSION)
                        {
                            return(null); // unexpected value
                        }

                        // Step 2: Read the ticket version number from the stream.
                        // LENGTH: 1 byte
                        int ticketVersion = ticketReader.ReadByte();

                        // Step 3: Read the ticket issue date from the stream.
                        // LENGTH: 8 bytes
                        long     ticketIssueDateUtcTicks = ticketReader.ReadInt64();
                        DateTime ticketIssueDateUtc      = new DateTime(ticketIssueDateUtcTicks, DateTimeKind.Utc);
                        DateTime ticketIssueDateLocal    = ticketIssueDateUtc.ToLocalTime();

                        // Step 4: Read the spacer from the stream.
                        // LENGTH: 1 byte
                        byte spacer = ticketReader.ReadByte();
                        if (spacer != 0xfe)
                        {
                            return(null); // unexpected value
                        }

                        // Step 5: Read the ticket expiration date from the stream.
                        // LENGTH: 8 bytes
                        long     ticketExpirationDateUtcTicks = ticketReader.ReadInt64();
                        DateTime ticketExpirationDateUtc      = new DateTime(ticketExpirationDateUtcTicks, DateTimeKind.Utc);
                        DateTime ticketExpirationDateLocal    = ticketExpirationDateUtc.ToLocalTime();

                        // Step 6: Read the ticket persistence field from the stream.
                        // LENGTH: 1 byte
                        byte ticketPersistenceFieldValue = ticketReader.ReadByte();
                        bool ticketIsPersistent;
                        switch (ticketPersistenceFieldValue)
                        {
                        case 0:
                            ticketIsPersistent = false;
                            break;

                        case 1:
                            ticketIsPersistent = true;
                            break;

                        default:
                            return(null);    // unexpected value
                        }

                        // Step 7: Read the ticket username from the stream.
                        // LENGTH: 1+ bytes (7-bit encoded integer char count + UTF-16LE payload)
                        string ticketName = ticketReader.ReadBinaryString();

                        // Step 8: Read the ticket custom data from the stream.
                        // LENGTH: 1+ bytes (7-bit encoded integer char count + UTF-16LE payload)
                        string ticketUserData = ticketReader.ReadBinaryString();

                        // Step 9: Read the ticket cookie path from the stream.
                        // LENGTH: 1+ bytes (7-bit encoded integer char count + UTF-16LE payload)
                        string ticketCookiePath = ticketReader.ReadBinaryString();

                        // Step 10: Read the footer from the stream.
                        // LENGTH: 1 byte
                        byte footer = ticketReader.ReadByte();
                        if (footer != 0xff)
                        {
                            return(null); // unexpected value
                        }

                        // Step 11: Verify that we have consumed the entire payload.
                        // We don't expect there to be any more information after the footer.
                        // The caller is responsible for telling us when the actual payload
                        // is finished, as he may have handed us a byte array that contains
                        // the payload plus signature as an optimization, and we don't want
                        // to misinterpet the signature as a continuation of the payload.
                        if (ticketBlobStream.Position != serializedTicketLength)
                        {
                            return(null);
                        }

                        // Success.
                        return(FormsAuthenticationTicket.FromUtc(
                                   ticketVersion /* version */,
                                   ticketName /* name */,
                                   ticketIssueDateUtc /* issueDateUtc */,
                                   ticketExpirationDateUtc /* expirationUtc */,
                                   ticketIsPersistent /* isPersistent */,
                                   ticketUserData /* userData */,
                                   ticketCookiePath /* cookiePath */));
                    }
                }
            }
            catch {
                // If anything goes wrong while parsing the token, just treat the token as invalid.
                return(null);
            }
        }