我在一个域上有几个应用程序共享单个唱歌的formsauthentication票证。我们还在每个页面上都有javascript,它会在会话到期前2分钟向用户发出警告,并允许他注销或延长他的会话。当倒计时达到0时,它们会自动注销。一切都很好。但是,当用户打开多个浏览器窗口或标签以处理各种应用程序时,它会失败。如果窗口A在用户在窗口B中工作时超时,则在下一个请求时将其从B中注销。
我有一个解决方案,但我似乎无法实现它。基本上,当呈现页面时,我会写出票证发行日期的刻度。然后,当自动注销时,我想ajax调用一个处理程序,看看这些刻度是否与当前的formauthentication票据滴答相匹配。如果它们不匹配,那么我知道另一个应用程序已刷新票证,我不会将它们注销。问题是我无法创建一个不更新票证的通用处理程序,因为我们使用了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请求的任何想法?
答案 0 :(得分:1)
在asp.net请求生命周期中,身份验证模块在httphandlers之前执行。一种解决方法是删除特定URL的身份验证模块,以便在httpsndler命中时不会续订您的故障单。像这样的东西
<location path="/MyApp/CompareTicket">
<system.web>
<httpModules>
<remove name="FormsAuthenticationModule"/>
</httpModules>
</system.web>
</location>
答案 1 :(得分:0)
为了做到这一点,您在域上有多个应用程序共享相同的表单身份验证令牌以用于SSO。当一个应用程序使令牌过期时,您希望它在所有其他应用程序中检测到该令牌。当时的应用程序。
由于令牌只是一个cookie,您可以配置一个连续运行的javascript函数(比如说每30秒)来检测表单auth cookie的存在。如果它消失(因为它将退出/过期),您可以使用该脚本发出一些警报等。
无论打开多少个窗口或正在运行哪些应用程序,这都可以正常工作。只要cookie存在,您就可以假设(客户端)用户已经过身份验证。