生成在当前新的ASP.NET会话的HttpContext [英] Generating a new ASP.NET session in the current HTTPContext

查看:140
本文介绍了生成在当前新的ASP.NET会话的HttpContext的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于对一些我们的产品在酝酿中,什么看起来是在时的易的问题解决了渗透测试的结果是谈到了是一个toughy。

As a result of a penetration test against some of our products in the pipeline, what looked to be at the time an 'easy' problem to fix is turning out to be a toughy.

不,这当然应该,我的意思是,为什么只想作为电流的HttpContext 生成一个全新的会话是那么难吗?离奇! Anyway-我写了一个没有教养的小工具类只管去做

Not that it should of course, I mean why would just generating a brand new session for the current HTTPContext be so difficult? Bizarre! Anyway- I've written a cheeky little utility class to "just do it":

(为code格式/高亮/ Visual Basic中的道歉我的必须的是做错了什么)

(apologies for code formatting/highlighting/Visual Basic I must be doing something wrong)


Imports System.Web
Imports System.Web.SessionState

Public Class SwitchSession

    Public Shared Sub SetNewSession(ByVal context As HttpContext)
        ' This value will hold the ID managers action to creating a response cookie
        Dim cookieAdded As Boolean
        ' We use the current session state as a template
        Dim state As HttpSessionState = context.Session
        ' We use the default ID manager to generate a new session id
        Dim idManager As New SessionIDManager()
        ' We also start with a new, fresh blank state item collection
        Dim items As New SessionStateItemCollection()
        ' Static objects are extracted from the current session context
        Dim staticObjects As HttpStaticObjectsCollection = _
            SessionStateUtility.GetSessionStaticObjects(context)
        ' We construct the replacement session for the current, some parameters are new, others are taken from previous session
        Dim replacement As New HttpSessionStateContainer( _
                 idManager.CreateSessionID(context), _
                 items, _
                 staticObjects, _
                 state.Timeout, _
                 True, _
                 state.CookieMode, _
                 state.Mode, _
                 state.IsReadOnly)
        ' Finally we strip the current session state from the current context
        SessionStateUtility.RemoveHttpSessionStateFromContext(context)
        ' Then we replace the assign the active session state using the replacement we just constructed
        SessionStateUtility.AddHttpSessionStateToContext(context, replacement)
        ' Make sure we clean out the responses of any other inteferring cookies
        idManager.RemoveSessionID(context)
        ' Save our new cookie session identifier to the response
        idManager.SaveSessionID(context, replacement.SessionID, False, cookieAdded)
    End Sub

End Class

它工作正常的请求的其余部分,并正确地识别自己作为新的会话(如 HTTPContext.Current.Session.SessionID 返回新生成的会话标识符) 。

It works fine for the remainder of the request, and correctly identifies itself as the new session (e.g. HTTPContext.Current.Session.SessionID returns the newly generated session identifier).

惊喜惊喜的话,当下次请求到达服务器时, HTTPContext.Session (一个 HTTPSessionState 对象)标识本身正确的的SessionID ,但 IsNewSession 设置为,并且是空的,失去所有在previous要求设置会话值。

Surprise surprise then, that when the next request hits the server, the HTTPContext.Session (an HTTPSessionState object) identifies itself with the correct SessionID, but has IsNewSession set to True, and is empty, losing all the session values set in the previous request.

所以,一定有什么特别之处从最初的请求,事件处理程序在这里,回调出现,一些它处理坚持要删除的previous HTTPSessionState 对象跨请求会话数据,或者只是我丢失的东西?

So there must be something special about the previous HTTPSessionState object being removed from the initial request, an event handler here, a callback there, something which handles persisting the session data across requests, or just something I'm missing?

任何人有任何魔法分享?

Anybody got any magic to share?

推荐答案

我想与大家分享我的魔法。其实,不,它没有神奇的。我们应该测试和进化code以上。
我只在cookie的,InProc会话模式下测试这些code。把这些方法你的页面中,并调用它,你需要重新生成的ID(请设置您的Web应用程序,以完全信任):

I would like to share my magic. Actually, no, its not yet magical.. We ought to test and evolve the code more. I only tested these code in with-cookie, InProc session mode. Put these method inside your page, and call it where you need the ID to be regenerated (please set your web app to Full Trust):

void regenerateId()
{
    System.Web.SessionState.SessionIDManager manager = new System.Web.SessionState.SessionIDManager();
    string oldId = manager.GetSessionID(Context);
    string newId = manager.CreateSessionID(Context);
    bool isAdd = false, isRedir = false;
    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;
    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;
    }
    object lockId = rqLockIdField.GetValue(ssm);
    if ((lockId != null) && (oldId !=null)) store.ReleaseItemExclusive(Context, oldId, lockId);
    rqStateNotFoundField.SetValue(ssm, true);
    rqIdField.SetValue(ssm, newId);
}

我一直在四处.NET源$ C ​​$ C(即均<一个可用href=\"http://referencesource.microsoft.com/netframework.aspx\">http://referencesource.microsoft.com/netframework.aspx), ,并发现有没有办法,我可以再生的SessionID没有黑客的会话管理机制的内部所以我做到这一点 - 破解SessionStateModule内部字段,所以它会在当前会话保存到一个新的ID也许当前HttpSessionState对象仍有在previous ID,但据我所知的SessionStateModule忽略了它。它只是使用内部_rqId字段时,它必须保存在某个地方的状态。我曾尝试其他方式,比如复制SessionStateModule到一个新的类与再生ID功能,(我打算用这个类)来代替SessionStateModule,但失败了,因为它目前有到其他内部类(比如InProcSessionStateStore参考资料)。使用反射黑客的缺点是,我们需要我们的应用程序设置为完全信任。

I have been digging around .NET Source code (that were available in http://referencesource.microsoft.com/netframework.aspx), and discovered that there is no way I could regenerate SessionID without hacking the internals of session management mechanism. So I do just that - hack SessionStateModule internal fields, so it will save the current Session into a new ID. Maybe the current HttpSessionState object still has the previous Id, but AFAIK the SessionStateModule ignored it. It just use the internal _rqId field when it has to save the state somewhere. I have tried other means, like copying SessionStateModule into a new class with a regenerate ID functionality, (I was planning to replace SessionStateModule with this class), but failed because it currently has references to other internal classes (like InProcSessionStateStore). The downside of hacking using reflection is we need to set our application to 'Full Trust'.

哦,如果你真的需要VB版本,请尝试以下:

Oh, and if you really need the VB version, try these :

Sub RegenerateID()
    Dim manager
    Dim oldId As String
    Dim newId As String
    Dim isRedir As Boolean
    Dim isAdd As Boolean
    Dim ctx As HttpApplication
    Dim mods As HttpModuleCollection
    Dim ssm As System.Web.SessionState.SessionStateModule
    Dim fields() As System.Reflection.FieldInfo
    Dim rqIdField As System.Reflection.FieldInfo
    Dim rqLockIdField As System.Reflection.FieldInfo
    Dim rqStateNotFoundField As System.Reflection.FieldInfo
    Dim store As SessionStateStoreProviderBase
    Dim field As System.Reflection.FieldInfo
    Dim lockId
    manager = New System.Web.SessionState.SessionIDManager
    oldId = manager.GetSessionID(Context)
    newId = manager.CreateSessionID(Context)
    manager.SaveSessionID(Context, newId, isRedir, isAdd)
    ctx = HttpContext.Current.ApplicationInstance
    mods = ctx.Modules
    ssm = CType(mods.Get("Session"), System.Web.SessionState.SessionStateModule)
    fields = ssm.GetType.GetFields(System.Reflection.BindingFlags.NonPublic Or System.Reflection.BindingFlags.Instance)
    store = Nothing : rqLockIdField = Nothing : rqIdField = Nothing : rqStateNotFoundField = Nothing
    For Each field In fields
        If (field.Name.Equals("_store")) Then store = CType(field.GetValue(ssm), SessionStateStoreProviderBase)
        If (field.Name.Equals("_rqId")) Then rqIdField = field
        If (field.Name.Equals("_rqLockId")) Then rqLockIdField = field
        If (field.Name.Equals("_rqSessionStateNotFound")) Then rqStateNotFoundField = field
    Next
    lockId = rqLockIdField.GetValue(ssm)
    If ((Not IsNothing(lockId)) And (Not IsNothing(oldId))) Then store.ReleaseItemExclusive(Context, oldId, lockId)
    rqStateNotFoundField.SetValue(ssm, True)
    rqIdField.SetValue(ssm, newId)

End Sub

这篇关于生成在当前新的ASP.NET会话的HttpContext的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆