【问题标题】:Call an ASMX webservice in javascript without resetting ASP.NET authentication timers在 javascript 中调用 ASMX Web 服务而不重置 ASP.NET 身份验证计时器
【发布时间】:2011-05-14 14:05:01
【问题描述】:

快速总结

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

更广泛的总结

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

这是因为我们的客户想让用户锁定记录,但如果他们浏览到其他站点,那么让其他人接管这些锁定的记录。也许客户端在站点上但处于非活动状态和在另一个站点上的区别似乎并不重要,但这有点无关紧要,我不会编写 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,但如果有人指出我真的很愚蠢并且实际上有更好的方法来尝试做我想做的事情,我会非常高兴正在做。

我正在考虑在这个阶段,也许我需要在 webmethod 中添加一些内容,说明该特定页面已停用多长时间,并使用该信息手动超时。这实际上听起来很容易,所以我想我现在就这样做。我仍然坚信一定有一种简单的方法可以完成我最初想做的事情。

更新

我认为我在这里的 cookie 操作方面非常糟糕,因为 .ASPXAUTH 和 ASP.NETSessionId cookie 都是 HttpOnly,这意味着浏览器会将它们从你手中拿走,你不能通过document.cookies 对象。所以我想说的是:

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

我知道怎么做 1. 所以我会从那里开始但是 2. 对我来说似乎更干净。

【问题讨论】:

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


    【解决方案1】:

    当您发现您在客户端 cookie 操作(或任何类型的客户端操作)方面不走运。操纵标头可能是可能的,但您必须在管道的早期拦截流量。我什至不知道服务本身是否有可能,但像 Zeus 这样的流量管理器可以做到。我不相信有可能以忽略端点和客户端请求的给定组合的方式配置会话引擎,尽管应该可以替换整个会话引擎,这将是无证的并且非常耗时我会想想。

    基本上,您需要在流量接触服务之前对其进行操作,否则您将无法解决此问题。 Session 并非设计为变体。

    【讨论】:

      【解决方案2】:

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

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

      这样,身份验证 cookie 将仅发送到您网站的 /admin 部分,如果您将 Web 服务放在根目录下,您可以使用 AJAX 对其进行 ping,而无需发送 cookie。

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

      【讨论】:

      • 这是个好主意,在这种情况下我需要排除单个路径。我会检查一下。
      • @Andrew,是的,我知道您需要排除,但不幸的是,path 参数适用于 cookie 的方式是包含。
      【解决方案3】:

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

      对我来说很容易,因为每个页面都使用相同的根 Site.Master 并且所有页面都继承自同一个基类。

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

      【讨论】:

        猜你喜欢
        • 2017-07-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-10
        • 1970-01-01
        • 2014-07-17
        • 2013-06-11
        相关资源
        最近更新 更多