Use ILSpy to view the Session. SessionID generation algorithm and sessionid generation algorithm.
Reason
In InProc mode, asp.net sessions are easy to lose and often need to be logged on again. distributed sharing is not supported.
So when we are studying how to implement a native Session in Redis, we wanted to use GUID as the key to store the cookie, and we were wondering whether we could implement the same id as the Session.
Implementation
ILSpy is an open-source. NET decompilation tool, which features simplicity, strength, and ease of use. In most cases, it completes your exploration of the internal code of an unknown assembly.
ILSpy: Click to download
In VS, we can know that SessionID is an attribute in the HttpSessionState class of the System. Web. SessionState namespace.
Search for HttpSessionState in ILSpy and find the Session attribute, which is created by the IHttpSessionState interface object.
View the constructor of HttpSessionState. The original IHttpSessionState is passed from the constructor.
I originally wanted to find out which object was passed through the search constructor, but ILSpy only provides the type, member, and constant search.
After a long time, I finally found the IHttpSessionState interface implementation class HttpSessionStateContainer
DelayedGetSessionId Method
CreateSessionId Method
The CreateSessionID method is defined in an interface.
Search for the CreateSessionID method to find the specific reality
Finally, find the class of the Create method.
Test
Specific Code:
internal static class SessionId { internal const int NUM_CHARS_IN_ENCODING = 32; internal const int ENCODING_BITS_PER_CHAR = 5; internal const int ID_LENGTH_BITS = 120; internal const int ID_LENGTH_BYTES = 15; internal const int ID_LENGTH_CHARS = 24; private static char[] s_encoding; private static bool[] s_legalchars; internal static bool IsLegit(string s) { if (s == null || s.Length != 24) { return false; } bool result; try { int num = 24; while (--num >= 0) { char c = s[num]; if (!SessionId.s_legalchars[(int)c]) { result = false; return result; } } result = true; } catch (IndexOutOfRangeException) { result = false; } return result; } internal static string Create(ref RandomNumberGenerator randgen) { if (randgen == null) { randgen = new RNGCryptoServiceProvider(); } byte[] array = new byte[15]; randgen.GetBytes(array); return SessionId.Encode(array); } static SessionId() { SessionId.s_encoding = new char[] { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5' }; SessionId.s_legalchars = new bool[128]; for (int i = SessionId.s_encoding.Length - 1; i >= 0; i--) { char c = SessionId.s_encoding[i]; SessionId.s_legalchars[(int)c] = true; } } private static string Encode(byte[] buffer) { char[] array = new char[24]; int num = 0; for (int i = 0; i < 15; i += 5) { int num2 = (int)buffer[i] | (int)buffer[i + 1] << 8 | (int)buffer[i + 2] << 16 | (int)buffer[i + 3] << 24; int num3 = num2 & 31; array[num++] = SessionId.s_encoding[num3]; num3 = (num2 >> 5 & 31); array[num++] = SessionId.s_encoding[num3]; num3 = (num2 >> 10 & 31); array[num++] = SessionId.s_encoding[num3]; num3 = (num2 >> 15 & 31); array[num++] = SessionId.s_encoding[num3]; num3 = (num2 >> 20 & 31); array[num++] = SessionId.s_encoding[num3]; num3 = (num2 >> 25 & 31); array[num++] = SessionId.s_encoding[num3]; num2 = ((num2 >> 30 & 3) | (int)buffer[i + 4] << 2); num3 = (num2 & 31); array[num++] = SessionId.s_encoding[num3]; num3 = (num2 >> 5 & 31); array[num++] = SessionId.s_encoding[num3]; } return new string(array); } }
Call:
public partial class Contact : Page { protected void Page_Load(object sender, EventArgs e) { string SessionId = CreateSessionID(Context); Response.Write(SessionId+"<br/>");
Response.Write(Session.SessionID); Response.End(); } private RandomNumberGenerator _randgen; public virtual string CreateSessionID(HttpContext context) { return SessionId.Create(ref this._randgen); } }
Effect: