After change SessionID data in Session variables is lost

After change SessionID data in Session variables is lost

Command "Manager.SaveSessionID" will remove all data of old sessionid. There is only one way to keep data. It's manual move data. You use the function below into login button:

...
using System.Web.SessionState;
using System.Reflection;

protected void ReGenerateSessionId()
    {
        SessionIDManager manager = new SessionIDManager();
        string oldId = manager.GetSessionID(Context);
        string newId = manager.CreateSessionID(Context);
        bool isAdd = false, isRedir = false;
        manager.RemoveSessionID(Context);
        manager.SaveSessionID(Context, newId, out isRedir, out isAdd);

        HttpApplication ctx = (HttpApplication)HttpContext.Current.ApplicationInstance;
        HttpModuleCollection mods = ctx.Modules;
        System.Web.SessionState.SessionStateModule ssm = (SessionStateModule)mods.Get("Session");
        System.Reflection.FieldInfo[] fields = ssm.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance);
        SessionStateStoreProviderBase store = null;
        System.Reflection.FieldInfo rqIdField = null, rqLockIdField = null, rqStateNotFoundField = null;

        SessionStateStoreData rqItem = null;
        foreach (System.Reflection.FieldInfo field in fields)
        {
            if (field.Name.Equals("_store")) store = (SessionStateStoreProviderBase)field.GetValue(ssm);
            if (field.Name.Equals("_rqId")) rqIdField = field;
            if (field.Name.Equals("_rqLockId")) rqLockIdField = field;
            if (field.Name.Equals("_rqSessionStateNotFound")) rqStateNotFoundField = field;

            if ((field.Name.Equals("_rqItem")))
            {
                rqItem = (SessionStateStoreData)field.GetValue(ssm);
            }
        }
        object lockId = rqLockIdField.GetValue(ssm);

        if ((lockId != null) && (oldId != null))
        {
            store.RemoveItem(Context, oldId, lockId, rqItem);
        }

        rqStateNotFoundField.SetValue(ssm, true);
        rqIdField.SetValue(ssm, newId);
    }

protected void Login_Click(object sender, EventArgs e)
{
    if (/*Login success*/)
    {
        ReGenerateSessionId(); // Change SessionID
        Session["User"] = user;
        Response.Redirect("Login_Success.aspx", true);
    }
}

Session Fixation Vulnerability in ASP.NET

protected void Page_Load(object sender, EventArgs e)
{
    if (Session["LoggedIn"] != null)
    {
        lblMessage.Text = "Congratulations !, you are logged in.";
        lblMessage.ForeColor = System.Drawing.Color.Green;
        btnLogout.Visible = true;
    }
    else
    {
        lblMessage.Text = "You are not logged in.";
        lblMessage.ForeColor = System.Drawing.Color.Red;
    }
}

protected void LoginMe(object sender, EventArgs e)
{
    // Check for Username and password (hard coded for this demo)
    if (txtU.Text.Trim().Equals("u") && txtP.Text.Trim().Equals("p"))
    {
        Session["LoggedIn"] = txtU.Text.Trim();
    }
    else
    {
        lblMessage.Text = "Wrong username or password";
    }
}

protected void LogoutMe(object sender, EventArgs e)
{
    Session.Clear();
    Session.Abandon();
    Session.RemoveAll();
}

Session loses keys and values when changing its ID

This is the expected result of telling the client to use a new session id. The values are still in the old session, but there is no connection between the old one and the new one. The Session is attached to the request early on in the request cycle, and changing a cookie value during the handling won't affect what session is attached to the user's requests until the next request comes in. What you want to do is clear the cookie when you first render the page, not when they click the button. There are some other subtleties to session management that I mention in my answer https://stackoverflow.com/a/45383679/10558.

You've tagged this question csrf but your solution does nothing for that attack. What resetting the session id prevents is session fixation.

How to Generate a new Session ID

The ASP.Net session management infrastructure does not expose a supported way to change your session id during the handling of a request. If writing supported code is important to you, there are several things to be aware of with the accepted answer.

  • Both CreateSessionID and SaveSessionID are marked "This method is not intended to be called from application code".
  • The SessionID provider is a pluggable type (see e.g. Implementing a custom SessionIDManager), so at the very least you would need to instantiate the correct type.
  • The session state attached to the HttpContext will remain associated with the initial session id, so anything you put in the session state bag will appear to be lost. Since there isn't anything you can do with the session once you've changed your id, it's kind of pointless to change your id this way.

Unfortunately, there isn't a supported way to do this without a round-trip. What you need to do is to wipe the session state cookie when you generate the login form. When the user submits the form back, the framework will call into the SessionIDManager to generate a new one. Wiping the session cookie correctly is slightly more complicated than most of the code samples show. The cookie name is another parameter configurable in the web.config. You need to read it from the configuration by accessing the property:

((System.Web.Configuration.SessionStateSection)ConfigurationManager.GetSection("system.web/sessionState")).CookieName

The session id cookie is not scoped to the application, so if there are two applications installed on the same server it's often desirable to have them use different cookie names, so this is required more commonly than you might think.

SessionIDManager.SaveSessionID(HttpContext, String, Boolean, Boolean) Method

Saves a newly created session identifier to the HTTP response.

Remarks

This method is not intended to be called from application code.

The SaveSessionID method is called by the SessionStateModule object during the AcquireRequestState event. The SaveSessionID method stores the session identifier in either the URL (when cookieless session state is used) or in a non-expiring session cookie.

By default, the SessionIDManager places a unique session identifier into a non-expiring session cookie and sets the cookieAdded parameter to true.

For a cookieless session state, the SessionIDManager object inserts a unique session identifier into the current URL, redirects the browser to the new URL that includes the session identifier, and then sets the redirected parameter to true.

For what design reason is Asp.Net Core SessionKey different than the SessionId? #151

The lifetimes are different. The true lifetime of a session (and SessionId) is controlled by the server. SessionKey is stored in the cookie and lives on the client for an indeterminate amount of time. If the session expires on the server and then the client sends a new request with the old SessionKey, a new session instance with a new SessionId is created, but stored using the old SessionKey so that we don't have to issue a new cookie.

Put another way, don't depend on things outside of your control. The client can keep and replay their SessionKey indefinitely, but it's the server that decides if that is really still the same session.

原文地址:https://www.cnblogs.com/chucklu/p/13178171.html