2

我在一个域上有几个应用程序,它们共享单点登录的表单身份验证票。我们还在每个页面上都有 javascript,会在用户会话到期前 2 分钟警告用户,并允许他注销或延长会话。当倒计时达到 0 时,它们会自动注销。这一切都很好。但是,当用户打开多个浏览器窗口或选项卡以在各种应用程序上工作时,它会惨遭失败。如果用户在窗口 B 中工作时窗口 A 超时,他们将在下一次请求时退出 B。

我有一个解决方案,但我似乎无法实现它。基本上,当页面呈现时,我会写出票证发行日期的刻度。然后,当自动注销时,我想 ajax 调用一个处理程序来查看这些滴答声是否与当前的表单验证票滴答声相匹配。如果它们不匹配,那么我知道另一个应用程序一直在刷新票证,我不会将它们注销。问题是我无法创建一个不更新票证的通用处理程序,因为我们使用了slidingexpiration = true。

function CompareTicket(ticks) {
    $.getJSON('http://localhost/MyApp/CompareTicket.ashx?t=' + ticks, function (data) {
        if (data == 0)
            SessionEnd();
        else
            SessionExtend();
    });
}

在下面的处理程序代码中,如果我在查询字符串中发送的值与当前工单的刻度相匹配,则数据返回为 0。不幸的是,仅仅请求处理程序的行为就会更新票证并总是发回新的滴答计数。

    public void ProcessRequest(HttpContext context)
    {
        context.Response.ContentType = "application/json";
        context.Response.ContentEncoding = Encoding.UTF8;

        long ticketTicks = ((FormsIdentity)context.User.Identity).Ticket.IssueDate.Ticks;
        if (ticketTicks == 0)
            context.Response.Write("0");
        else
        {
            long ticks = 0;
            if (long.TryParse(context.Request.QueryString["t"], out ticks))
            {
                if (ticketTicks == ticks)
                    context.Response.Write("0");
                else
                    context.Response.Write(ticketTicks.ToString());
            }
            else
                context.Response.Write("0");
        }
    }

关于如何在不扩展票证的情况下从服务器获取 JSON 请求的任何想法?

4

2 回答 2

1

在 asp.net 请求生命周期中,身份验证模块在 httphandlers 之前执行。一种解决方法是删除特定 url 的那些身份验证模块,因此当 httphandler 被点击时,它不会更新您的票证。像这样的东西

<location path="/MyApp/CompareTicket">
    <system.web>
        <httpModules>
            <remove name="FormsAuthenticationModule"/>
        </httpModules>
    </system.web>
</location>
于 2012-07-13T19:12:40.843 回答
0

为了弄清楚这一点,域上的多个应用程序共享相同的表单身份验证令牌以用于 SSO。当一个应用程序使令牌过期时,您希望它同时在所有其他“打开”的应用程序中检测到这一点。

由于令牌只是一个 cookie,您可以配置一个持续运行的 javascript 函数(例如每 30 秒)来检测表单身份验证 cookie 的存在。如果它消失(因为它会注销/过期),您可以使用脚本来引发一些警报等。

无论打开了多少个窗口或正在运行哪些应用程序,这都将起作用。只要 cookie 存在,您就可以假设(客户端)用户已通过身份验证。

于 2011-10-08T19:17:43.650 回答