在javascript中调用ASMX Web服务而不重置ASP.NET身份验证计时器

时间:2010-11-23 16:29:43

标签: asp.net ajax xmlhttprequest asmx iis-7.5

快速摘要

从客户端ping回ajax中的webservice使用户的会话保持活动状态,我不希望这种情况发生。

更广泛的摘要

对于我们正在开发的网站,我们需要客户端(在js中)ping回服务器上的Web服务(ASMX)(IIS7.5)。这恰好让服务器知道用户仍然在网站上,并且没有浏览到其他网站。

这是因为我们的客户希望让用户锁定记录,但如果他们浏览其他网站,则让其他人接管这些锁定的记录。也许客户端在网站上但非活动状态和另一个网站之间的区别似乎并不重要,但这有点无关紧要,我不会编写UI规范,我只需要让它工作。

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

我想我可以通过删除作为服务器ping的XMLHttpRequest中的ASP.NET_SessionId和.ASPXAUTH cookie来解决这个问题,但我无法弄清楚如何执行此操作。

这就是我的网络服务&方法定义如下:

[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从循环中取出,这样它就不会使会话保持活动状态,但我不知道如何执行此操作

虽然问题的标题集中在清除标题中的cookie,但如果有人指出我真的很愚蠢并且实际上有更好的方法尝试做我的事情,我会非常高兴。正在做。

我正在考虑在这个阶段,我可能需要在web方法中添加一些内容,说明此特定页面处于非活动状态的时间长度,并使用该知识手动超时。这实际上听起来很简单,所以我想我现在就会这样做。我仍然相信必须有一种简单的方法来做我原本想做的事情。

更新

我认为我在cookie操作方面非常紧张,因为.ASPXAUTH和ASP.NETSessionId cookie都是HttpOnly,这意味着浏览器将它们从你手中夺走,你无法通过它访问它们document.cookies对象。所以我想说让我留下:

  1. 更新我的SessionAlive webmethod以跟踪每个请求,以便我可以判断用户在页面上空闲了多长时间并在需要时超时
  2. 在服务器端以某种方式标记.asmx页面,使其脱离正常的身份验证/会话跟踪流程
  3. 我知道该怎么做1.所以我会从那里开始,但2.对我来说似乎更清洁。

3 个答案:

答案 0 :(得分:1)

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

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

这样,身份验证cookie只会发送到您网站的/admin部分,如果您将您的网络服务放在根网站上,您可以使用AJAX对其进行ping操作,而无需发送Cookie。

另一个选择是将此Web服务简单地托管到一个单独的虚拟目录中。

答案 1 :(得分:0)

正如您发现自己运行客户端cookie(或任何类型的客户端操作)一样。可能有可能操作标题,但您必须在管道中尽早拦截流量。我甚至不知道它是否可以在服务本身,但像Zeus这样的流量管理器可以做到。我不相信有可能以忽略端点和客户端请求的给定组合的方式配置会话引擎,尽管应该可以替换整个会话引擎,这些引擎将是未记录的并且非常耗时我会认为

基本上,您需要在接触服务之前操纵流量,否则您将无法解决此问题。会话的目的不是变体。

答案 2 :(得分:0)

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

对我来说非常简单,因为每个页面使用相同的根Site.Master并且所有页面都从相同的基类继承。

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