/// <summary> /// Save the session into the response /// </summary> /// <param name="session">Session to save</param> /// <param name="response">Response to save into</param> public void Save(ISession session, Nancy.Response response) { this.ExpireOldSessions(); if (session == null || !session.HasChanged) { return; } var id = session["_id"] as string; if (null == id) { // TODO: warn return; } // Persist the session session.Delete("_id"); Await(RethinkDbSessionStore.UpdateSession(currentConfiguration, id, session)); // Encrypt the session Id in the cookie var cryptographyConfiguration = this.currentConfiguration.CryptographyConfiguration; var encryptedData = cryptographyConfiguration.EncryptionProvider.Encrypt(id); var hmacBytes = cryptographyConfiguration.HmacProvider.GenerateHmac(encryptedData); var cookieData = HttpUtility.UrlEncode(String.Format("{0}{1}", Convert.ToBase64String(hmacBytes), encryptedData)); var cookie = new NancyCookie(this.currentConfiguration.CookieName, cookieData, true) { Domain = this.currentConfiguration.Domain, Path = this.currentConfiguration.Path }; response.WithCookie(cookie); }
/// <summary> /// Expire old sessions /// </summary> public void ExpireOldSessions() { if (currentConfiguration.ExpiryCheckFrequency >= DateTime.Now - this.LastExpiryCheck) { return; } Await(RethinkDbSessionStore.ExpireSessions(currentConfiguration)); this.LastExpiryCheck = DateTime.Now; }
/// <summary> /// Create a new session /// </summary> /// <param name="dictionary">The dictionary to use for the session</param> /// <returns>The session object</returns> private ISession CreateNewSession(IDictionary <string, object> dictionary) { var id = Guid.NewGuid().ToString(); Await(RethinkDbSessionStore.NewSession(currentConfiguration, id)); var session = new Session(dictionary); session["_id"] = id; return(session); }
/// <summary> /// Loads the session from the request /// </summary> /// <param name="request">Request to load from</param> /// <returns>ISession containing the load session values</returns> public ISession Load(Request request) { this.ExpireOldSessions(); var dictionary = new Dictionary <string, object>(); // Get the session Id from the encrypted cookie var cookieName = this.currentConfiguration.CookieName; var hmacProvider = this.currentConfiguration.CryptographyConfiguration.HmacProvider; var encryptionProvider = this.currentConfiguration.CryptographyConfiguration.EncryptionProvider; if (!request.Cookies.ContainsKey(cookieName)) { return(CreateNewSession(dictionary)); } var cookieData = HttpUtility.UrlDecode(request.Cookies[cookieName]); var hmacLength = Base64Helpers.GetBase64Length(hmacProvider.HmacLength); if (cookieData.Length < hmacLength) { return(CreateNewSession(dictionary)); } var hmacString = cookieData.Substring(0, hmacLength); var encryptedCookie = cookieData.Substring(hmacLength); var hmacBytes = Convert.FromBase64String(hmacString); var newHmac = hmacProvider.GenerateHmac(encryptedCookie); var hmacValid = HmacComparer.Compare(newHmac, hmacBytes, hmacProvider.HmacLength); if (!hmacValid) { return(CreateNewSession(dictionary)); } // Get the session itself from the database var id = encryptionProvider.Decrypt(encryptedCookie); var session = Await(RethinkDbSessionStore.RetrieveSession(currentConfiguration, id)); if (null == session) { return(CreateNewSession(dictionary)); } if (currentConfiguration.UseRollingSessions) { Await(RethinkDbSessionStore.UpdateLastAccessed(currentConfiguration, id)); } return(session); }
/// <summary> /// Initializes a new instance of the <see cref="RethinkDbSessions"/> class. /// </summary> /// <param name="configuration">Cookie based sessions configuration.</param> public RethinkDbSessions(RethinkDbSessionConfiguration configuration) { if (configuration == null) { throw new ArgumentNullException("configuration"); } if (!configuration.IsValid) { throw new ArgumentException("Configuration is invalid", "configuration"); } this.currentConfiguration = configuration; this.Await(RethinkDbSessionStore.SetUp(this.currentConfiguration)); }