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); }
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); }
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)); }
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); }
//////////////////////////////////////////////////////////// // 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); } } }
//////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////// // 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); }
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); }
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); } } } } } }
// 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); } }