【问题标题】:ASP to ASP.NET Session VariablesASP 到 ASP.NET 会话变量
【发布时间】:2012-06-30 08:33:27
【问题描述】:

我们有一个经典 ASP 网站,我们正在根据需要慢慢迁移到 ASP.NET。

问题当然是经典的 asp 和 ASP.NET 是如何处理 Sessions 的。在花了最后几个小时研究网络后,我发现了很多文章,但没有一篇比其他文章更突出。

在传统的 asp 和 asp.net 之间传输会话变量是否有最佳实践?安全性是必须的,非常感谢任何带有示例的解释。

【问题讨论】:

  • 我应该在本周末完成最适合我们需求的解决方案。我还会提到一些其他的方法。保持发布。

标签: asp.net session asp-classic


【解决方案1】:

将单个会话变量从经典 asp 传递到 .net 服务器端(向客户端隐藏您的会话值)的简单桥梁是这样的:

  • 在 ASP 端:输出会话的 asp 页面,例如调用它。 asp2netbridge.asp

    <%
    'Make sure it can be only called from local server '
    if (request.servervariables("LOCAL_ADDR") = request.servervariables("REMOTE_ADDR")) then
        if (Request.QueryString("sessVar") <> "") then
            response.write Session(Request.QueryString("sessVar"))
        end if
    end if
    %>
    
  • 在 .net 端,远程调用该 asp 页面。 :

    private static string GetAspSession(string sessionValue)
     {
        HttpWebRequest _myRequest = (HttpWebRequest)WebRequest.Create(new Uri("http://yourdomain.com/asp2netbridge.asp?sessVar=" + sessionValue));
        _myRequest.ContentType = "text/html";
        _myRequest.Credentials = CredentialCache.DefaultCredentials;
        if (_myRequest.CookieContainer == null)
            _myRequest.CookieContainer = new CookieContainer();
        foreach (string cookieKey in HttpContext.Current.Request.Cookies.Keys)
        {
            ' it is absolutely necessary to pass the ASPSESSIONID cookie or you will start a new session ! '
            if (cookieKey.StartsWith("ASPSESSIONID")) {
                HttpCookie cookie = HttpContext.Current.Request.Cookies[cookieKey.ToString()];
                _myRequest.CookieContainer.Add(new Cookie(cookie.Name, cookie.Value, cookie.Path, string.IsNullOrEmpty(cookie.Domain)
                    ? HttpContext.Current.Request.Url.Host
                    : cookie.Domain));
            }
        }
        try
        {
            HttpWebResponse _myWebResponse = (HttpWebResponse)_myRequest.GetResponse();
    
            StreamReader sr = new StreamReader(_myWebResponse.GetResponseStream());
            return sr.ReadToEnd();
        }
        catch (WebException we)
        {
            return we.Message;
        }
    }
    

【讨论】:

  • 这就是我最终编码的方式。我忘了发布我的答案。
  • 这里的 sessionValue 值是多少?
  • @Sajeetharan 不确定您的问题是什么。 sessionValue 是您要共享的任何会话变量,因此是任何字符串参数
  • @AardVark71 假设我有一个名为“uname”的会话变量,应该如何修改此代码? '确保它只能从本地服务器调用'是什么意思?
  • @Sajeetharan 1) 在 .Net 端使用 GetAspSession("uname") 然后在经典的 asp 端使用 Session("uname") ; 2) if 语句确保只能从服务器调用它[即通过来自该服务器的 .net 代码)(request.servervariables("LOCAL_ADDR") = request.servervariables("REMOTE_ADDR"))
【解决方案2】:

我使用了一个 ajax 桥接器(因为需要一个更好的术语),特别是一个经典的 asp 页面,它将所有会话变量读取到具有 guid 的数据库中,然后重定向到一个 .net 页面,在查询字符串,asp.net 页面从 sql 中读取给定的 guid,并将这些变量创建为会话。

例如,在经典的 asp 中(伪代码 - 只是为了给您一个想法,在您的代码中使用参数化查询等):

'#### Create GUID
Dim GUID 'as string
GUID = CreateWindowsGUID() '#### Lots of methods on http://support.microsoft.com/kb/320375

'#### Save session to sql
For Each SessionVar In Session.Contents
   db.execute("INSERT INTO SessionBridge (GUID, Key, Value) VALUES ('" & GUID & "', '" & SessionVar & "', '" & session(SessionVar) & "')")
Next

然后,在 .net 页面中:

'#### Fetch GUID
Dim GUID as string = Request.QueryString("GUID")
session.clear

'#### Fetch from SQL
db.execute(RS, "SELECT * FROM SessionBridge WHERE GUID = '" & GUID & "'")
For Each db_row as datarow in RS.rows
    Session(db_row("Key")) = db_row("Value")
Next

正如我所说,这是非常粗糙的伪代码,但您可以使用简单的后台 ajax 函数调用 asp,然后调用给定 GUID 的 .net 页面。

这样做的好处是不会将所有变量和值暴露给客户端(就像 post 方法那样)。

【讨论】:

  • 这与我认为的好解决方案非常相似。但是基于 Microsoft 的一篇文章感到困惑,该文章采用了类似的方法,需要注册安全 DLL 等。我不明白为什么这是必要的。这是链接msdn.microsoft.com/en-us/library/aa479313.aspx。知道为什么 MSDN 文章中提到的所有额外工作都在那里吗?如果有必要?
  • @PsychoDUCK 我认为微软的版本更通用。您可以将任何对象存储在会话变量中(不仅仅是字符串),所以猜测他们的解决方案可能会处理这个问题。但是,如果您只将字符串存储在会话变量中,那么这可以正常工作(只要确保会话值没有引号,否则此处发布的指令可能会中断)
【解决方案3】:

它们使用不同的会话,因此您需要自己设计一些传输变量的方法。您可以将它们包含在 cookie 中,或者通过 HTTP POST(即带有隐藏字段的表单)将它们发送到 asp.net 端。

或者,您可以废弃使用会话存储并将每个用户/会话的所有内容都粘贴到数据库中,然后只需通过上述建议之一将会话密钥从经典 ASP 传递到 ASP.NET。我知道这听起来像是你在重新发明轮子,但这可能是你无法绕过的情况之一。

【讨论】:

  • 我希望这篇文章考虑所有解决方案并确定或创建“最佳”解决方案,同时牢记安全性。为什么一个比另一个好。显然,基于某些场景,一种会比另一种更好,但我在网上找不到明确的答案。
  • 这个问题没有明确的答案,而且不可能将一个答案标记为“最佳”,因为这是一个非常主观的术语。您必须进行一些研究并确定最适合您需求的方法。这些只是一些想法,您应该根据自己的需要进行研究。
  • 虽然出于安全考虑,我会避免将变量发送到客户端(通过 cookie、隐藏表单字段等)。考虑类似于我的第二段的解决方案,您在内部存储变量,并向客户端发送标识符。
【解决方案4】:

我有一个网站可以执行该操作。秘诀是使用带有asp函数response.redirect的中间页面

<%
client_id = session("client_id")
response.redirect "aspx_page.aspx?client_id=" & client_id
%>

这是一个提取经典 asp 会话变量 client_id 并将其传递给 aspx 页面的示例。您的 aspx 页面将需要从那里处理它。

这需要位于经典 asp 页面的顶部,上面没有任何类型的 HTML。 IIS 将在服务器上处理这个并重定向到带有附加查询字符串的 aspx 页面,而不将数据发送到客户端计算机。它非常快。

【讨论】:

  • "... 不向客户端机器发送数据" - Response.Redirect 将包含 client_id 的 url 发送到客户端机器。
  • @joe 可以 Server.Transfer 在这里工作还是我遗漏了一些明显的东西?
【解决方案5】:

如果其他人在这里偶然发现寻求帮助,另一种可能的选择是使用 cookie。 cookie 的好处是您可以存储合理数量的数据,然后将该数据保存到您的 .Net 应用程序(或其他 Web 应用程序)。暴露 cookie 存在安全风险,因为该数据很容易被操纵或伪造。我不会在 cookie 中发送敏感数据。这里 cookie 仅存储一个唯一标识符,可用于从表中检索数据。

方法:

  1. 从您的经典 asp 页面获取您需要的会话数据。店铺 表中的这些数据以及唯一的哈希和时间戳。
  2. 将哈希值存储在一个短暂的 cookie 中。
  3. 重定向到您需要去的任何页面并读取 cookie 中的哈希值。
  4. 检查 cookie 中的哈希在数据库中是否过期。如果有效,请将您需要的数据发送回您的页面,然后使哈希过期,使其无法重复使用。

我使用了 SHA 256 哈希,它是用户的唯一标识符、会话 ID 和当前时间戳的组合。哈希仅在几分钟内有效,并在读取时过期。这个想法是为需要在有效哈希过期之前猜测有效哈希的攻击者限制窗口。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-09
    • 1970-01-01
    • 2012-03-26
    • 2016-09-03
    • 1970-01-01
    • 1970-01-01
    • 2013-01-31
    相关资源
    最近更新 更多