代码之家  ›  专栏  ›  技术社区  ›  Andrew Barrett

在不重置ASP.NET身份验证计时器的情况下,在JavaScript中调用ASMX WebService

  •  2
  • Andrew Barrett  · 技术社区  · 14 年前

    快速总结

    从客户机Ping返回Ajax中的WebService将保持用户会话的活动状态,我不希望发生这种情况。

    更广泛的总结

    对于我们正在开发的网站,我们需要客户机在JS中对服务器(IIS7.5)上的WebService(ASMX)执行ping操作。这会让服务器知道用户仍然在站点上,并且没有浏览到其他站点。

    这是因为我们的客户想让用户锁定记录,但如果他们浏览到其他网站,然后让其他人接管这些锁定的记录。也许客户机在站点上但不活跃和在另一个站点之间的区别似乎无关紧要,但这有点无关紧要,我不需要编写UI规范,我只需要让它工作就行了。

    我的问题是,ping通过标准的表单身份验证超时机制阻止用户在服务器上超时。这并不奇怪,因为在后台有30秒的ping,使会话保持活动状态。即使我们想知道用户是否仍在站点上,我们也希望遵守正常的表单身份验证超时机制。

    我想我可以通过删除XMLHttpRequest(即服务器ping)中的ASP.NET_SessionID和.aspxauth cookies来解决这个问题,但我不知道如何解决这个问题。

    以下是我的Web服务方法的定义方式:

    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [ScriptService]
    public class PingWS : WebService
    {
        [WebMethod]
        public void SessionActive(string sessionID)
        {
            // does stuff here
        }
    

    这就是我在JS中调用它的方式(请求通过HTTPS,:

    $.ajax({
        type: "POST",
        url: "PingWS.asmx/SessionActive",
        data: 'sessionID=' + aspSessionID + '}',
        beforeSend: function (xhr) {
            xhr.setRequestHeader('Cookie', '');
            xhr.setRequestHeader('Cookie', 'ASP.NET_SessionId=aaa; .ASPXAUTH=bbb;');
        },
        dataType: "json"
    });
    

    我尝试使用setRequestHeader,但它只是追加到头,而不是覆盖头,而且IIS很乐意忽略我添加的垃圾。

    我在想,也许我应该在服务器端尝试这样做,有人将pingws.asmx从循环中去掉,这样它就不会保持会话活动,但我不确定如何做。

    尽管这个问题的题目是集中在清除头条中的曲奇,但如果有人指出我真的很蠢,而且实际上还有更好的方法来尝试做我正在做的事情,我会非常高兴。

    我在想,在这个阶段,也许我需要向webmethod添加一些内容,说明这个特定页面处于非活动状态的时间,并使用这些知识手动超时。这听起来很简单,所以我想我现在就这么做。尽管如此,我仍然相信一定有一个简单的方法来做我最初想做的事情。

    更新

    我认为我在cookie操作方面做得很糟糕,因为.aspxauth和asp.netsessionid cookie都是httponly,这意味着浏览器会将它们从您的手中带走,您无法通过document.cookies对象访问它们。所以我想说,这让我:

    1. 更新我的sessionalive webmethod来跟踪每个请求,这样我就可以知道用户在页面上空闲了多长时间,如果需要,可以超时。
    2. 在服务器端以某种方式标记.asmx页,使其脱离正常的身份验证/会话跟踪流

    我知道怎么做1。那我就从那里开始,不过2点。在我看来更干净了。

    3 回复  |  直到 14 年前
        1
  •  1
  •   Darin Dimitrov    14 年前

    您可以将身份验证cookie限制为给定路径:

    <authentication mode="Forms">
      <forms path="/admin" />
    </authentication>
    

    这样,身份验证cookie将只发送到 /admin 站点的一部分,如果将Web服务放在根目录下,则可以使用Ajax对其执行ping操作,而无需发送cookie。

    另一种选择是简单地将这个WebService托管到一个单独的虚拟目录中。

        2
  •  0
  •   annakata    14 年前

    当你发现自己对客户端cookie操作(或任何类型的客户端操作)的运气不佳时。操作头可能是可能的,但您必须在管道的早期拦截流量。我甚至不知道服务本身是否可行,但像宙斯这样的流量管理器可以做到。我认为不可能配置会话引擎以忽略端点和客户机请求的给定组合,尽管应该可以替换整个会话引擎,但这将是未记录和非常耗时的,我认为。

    基本上,您需要在它接触到服务之前操纵流量,否则您将无法解决这个问题。会话未设计为变量。

        3
  •  0
  •   Andrew Barrett    14 年前

    有一个服务器端的答案。基本上,您禁用表单身份验证上的滑动超时,然后自己手动滑动超时,并跳过它进行ping。

    对我来说很容易,因为每个页面都使用相同的根站点。master和所有页面都继承自相同的基类。

    总结如下: http://picometric.blogspot.com/2009/04/manual-sliding-expiration.html