【问题标题】:Change ASP.Net Session ID - Call from Desktop App via AJAX更改 ASP.Net 会话 ID - 通过 AJAX 从桌面应用程序调用
【发布时间】:2019-07-06 06:21:51
【问题描述】:

我有一个旧的 VB6 应用程序 - 我需要通过 Web 浏览器访问 ASP.net 站点。我打开浏览器并成功调用了 ASP 站点。我需要 VB6 应用程序知道 Web 浏览器会话何时关闭。 Web 浏览器会话打开时,需要禁用 VB 应用程序表单(或保存按钮)。 (我不想用windows进程的进程ID来检查这个。)

我的想法是:

  • 也许是跨域cookies? (安全?)
  • 我的 VB6 应用程序能够调用服务器 WebMethods
  • 在使用但两个应用程序的数据库中保存会话 ID?

一些建议会很好。非常感谢。

【问题讨论】:

  • 可能最好简单地调用一个服务器函数(Web 服务),它可以让你知道会话是否处于活动状态(直接),(函数 SessionsExist() 作为布尔值或任何你想要的调用它)并在您的 VB 应用程序中使用该信息(链接到 Web 服务:msdn.microsoft.com/en-us/library/hh128052.aspx
  • 是的,听起来不错 - 但是当我在 Web 服务中调用 SessionsExist() 时,我如何知道 VB 6 应用程序中的 ASP.NET_SessionId?
  • 使用 SessionIDManager 对象 (docs.microsoft.com/en-us/dotnet/api/…) 阅读文档中 REMARKS 标题下的第二段...(段落开头...'默认情况下,SessionID 值在 cookie 中发送')

标签: c# asp.net cookies vb6 session-cookies


【解决方案1】:

公司内部申请。

桌面应用 (VB6)

  • 允许 VB6 应用程序联系 Asp 服务的代码。在任何 Asp.Net 页面上创建一个额外的 [WebMethod],在这种情况下,已将“IsWindowOpen”方法添加到 test.aspx 页面(请参见下面的红色文本)
  • 向 ASP.Net 服务发送 JSON 消息以查询是否设置了 WINDOWS_STATUS 会话变量(这告诉我们浏览器窗口是否打开\关闭)。
  • 当使用参数(计划 ID 等)向 Asp.Net 站点发起攻击时,我们将为“会话 ID”发送一个额外的参数。

  • 在 VB6 应用程序中随机生成一个 Session Id [随机:24 个字符长,小写,数字介于 0-5 之间],这是复制 Asp.Net 框架将如何生成自己的 Session Id HTML 和 C# 之间的通信。然后,我们将使用我们自己随机生成的会话 ID 覆盖 Asp.Net 提供给我们的 Asp.Net 会话 ID。

检查是否在 VB6 中设置了 ASP.Net 会话变量:

Private Sub Command1_Click()
    Dim objHTTP As Object
    Dim Json As String
    Dim result As String

    ' === Check if Browser Session is open ===
    Set objHTTP = CreateObject("MSXML2.ServerXMLHTTP")
    url = "http://dub-iisdev/SessionTest/test.aspx/IsWindowOpen"

    objHTTP.open "POST", url, False

    objHTTP.setRequestHeader("cookie") = "ASP.NET_SessionId=" + txtCookie.Text ' Required twice
    objHTTP.setRequestHeader("cookie") = "ASP.NET_SessionId=" + txtCookie.Text ' Required twice

   objHTTP.setRequestHeader "Content-type", "application/json"

   objHTTP.send (Json)

   result = objHTTP.responseText

   txtOutput.Text = result

   Set objHTTP = Nothing
End Sub

ASP.Net

我们需要一些管道: 一种设置 ASP.Net 会话 ID 的小方法 一个小的关闭 aspx 页面,当我们离开浏览器时将运行一些代码,以及 我们现有页面中的一些额外的 C# 方法和 JavaScript。

1.设置会话 ID:

将变量从旧会话复制到新位置

protected void ReGenerateSessionId(string newsessionID)
{
    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, newsessionID, 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, newsessionID);
}

您的第一个登录页面将设置新的会话 ID(来自 VB6)参数发送到服务器 - 使用上面的 ReGenerateSessionId 类。

在此代码向 Asp.Net 执行实例后,我们的 VB6 实例将具有相同的 HTTP 通信会话 ID

protected void Page_Load(object sender, EventArgs e)
{
    // Simulate Session ID coming in from VB6...
    string sessionId;
    Random rnd = new Random();
    sessionId = "asdfghjklqwertyuiop12345" [24 char - a to z (small) & 0-5]
    // Set new session variable and copy variable from old session to new location
    ReGenerateSessionId(sessionId);

    // Put something into the session
    HttpContext.Current.Session["SOME_SESSION_VARIABLE_NAME"] = "Consider it done!";
}

2。打开\关闭浏览器

其中一个 ASP.Net 页面需要具有三个新的 WebMethod:SetOpenWindow、SetClosingWindow 和 IsWindowOpen

打开浏览器:

C#。设置打开窗口: 这将通过 .ready JavaScript 从您的第一个(或任何需要的)HTML 页面调用。页面加载后,JavaScript 将简单地触发对 SetOpwnWindow Web 方法的 Ajax 调用。该方法会将 Session 变量 WINDOW_STATUS 设置为 OPEN。

[WebMethod()]
[ScriptMethod(UseHttpGet = false)]
public static string SetOpenWindow()
{
    HttpContext.Current.Session["WINDOW_STATUS"] = "OPEN";
    return "Status:" + HttpContext.Current.Session["WINDOW_STATUS"];
}

ASPX。页面加载后,从 Ajax 调用 SetOpenWindow。这会将 WINDOW_STATUS 设置为 OPEN

<script src=”Scripts/jquery-1.4.1.js" type="text/javascript"></script>
<script type="text/javascript">
    $(document).ready(function () {

        jQuery.ajax({
            url: 'test.aspx/SetOpenWindow',
            type: "POST",
            dataType: "json",
            data: "",
            contentType: "application/json; charset=utf-8",
            success: function (data) {}//alert(JSON.stringify(data));
        });

        $("#form1").submit(function () {
            submitted = true;
        });    
    });
</script>

关闭浏览器:

在可以关闭浏览器窗口的页面上,调用 JavaScript 以捕获浏览器窗口何时关闭(方便将其添加到母版页而不是每个页面!)。这会调用 ClosingSessionPage aspx 页面来运行 SetClosingWndow 网络方法:

<script type=”text/javascript”>
    var submitted = false;

    function wireUpWindowUnloadEvents() {
        $(document).on('keypress', function (e) { if (e.keyCode == 116) { callServerForBrowserCloseEvent(); } }); // Attach the event keypress to exclude the F5 refresh
        $(document).on("click", "a", function () { callServerForBrowserCloseEvent(); }); // Attach the event click for all links in the page
    }

    $(window).bind("onunload", function () { if (!submitted) { callServerForBrowserCloseEvent(); event.preventDefault(); } });
    $(window).bind("beforeunload", function () { if (!submitted) { callServerForBrowserCloseEvent(); event.preventDefault(); } });
    window.onbeforeunload = function () { if (!submitted) { callServerForBrowserCloseEvent(); } };
    window.onunload = function () { if (!submitted) { callServerForBrowserCloseEvent(); } };
    $(window).bind("onunload", function () { if (!submitted) { callServerForBrowserCloseEvent();event.preventDefault();} });

    function callServerForBrowserCloseEvent() {
        window.open("ClosingSessionPage.aspx", "Closing Page", "location=0,menubar=0,statusbar=1,width=1,height=1"); }

    function btn_onclick() { open(location, '_self').close(); }

</script>

上面的关闭 JavaScript 方法重定向到关闭的 aspx 页面以运行一些 ajax,然后关闭自身 - Ajax 调用 SetClosingWindow 会话 WINDOW_STATUS 变量到 CLOSED。

<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server" title="Closing Session">

    <script src="Scripts/jquery-1.4.1.js" type="text/javascript"></script>
    <script type="text/javascript">
        $(document).ready(function () {
            jQuery.ajax({
                url: 'test.aspx/SetClosingWndow',
                type: "POST",
                dataType: "json",
                data: "",
                contentType: "application/json; charset=utf-8",
                success: function (data) {
                    window.close();
                } });  });
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <p>Closing browser session, please wait.</p>
    </form>
</body>
</html>

C# SetClosingWindow 当浏览器窗口关闭并将 WINDOW_STATUS 设置为 CLOSED 时从 Ajax JavaScript 调用:

[WebMethod()]
[ScriptMethod(UseHttpGet = false)]
public static string SetClosingWndow()
{
    HttpContext.Current.Session["WINDOW_STATUS"] = "CLOSED";
    ScriptManager.RegisterClientScriptBlock((Page)(HttpContext.Current.Handler), typeof(Page), "closePage", "window.close();", true);
    return "Status:" + HttpContext.Current.Session["WINDOW_STATUS"];
}

3.浏览器是否打开?

VB6 在需要知道浏览器窗口是打开还是关闭时调用的 ASP.Net WebMethod。

[WebMethod()]
[ScriptMethod(UseHttpGet = false)]
public static string IsWindowOpen()
{
    string isWindowOpen = HttpContext.Current.Session["WINDOW_STATUS"] != null ? HttpContext.Current.Session["WINDOW_STATUS"].ToString() : "CLOSED";

    return "IsWindowOpen:" + isWindowOpen;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-17
    • 1970-01-01
    • 2011-12-26
    • 1970-01-01
    • 2011-02-06
    • 2011-01-14
    相关资源
    最近更新 更多