我有一个ASP.Net MVC4应用程序,其中包含一些包含许多Ajax操作的页面。我试图处理会话到期后发生的事情。
目前,如果上下文报告当前请求isAuthenticated,我的代码会强制在Session_Start()上运行“FormsAuthentication.SignOut()”。
protected void Session_Start(object sender, EventArgs e) {
if (HttpContext.Current.Request.IsAuthenticated) {
FormsAuthentication.SignOut(); // Drop all the information held in the session
// now continue with request....
}
}
下一部分是“HandleUnauthorizedRequest”的覆盖,它应该捕获未授权的请求,测试它是否是ajax请求,如果没有则继续,否则返回一个特定的JSON来指示失败。
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) {
if (filterContext.HttpContext.Request.IsAjaxRequest()) {
filterContext.Result = new JsonResult { Data = new { ajaxUnauthorizedMessage = "sorry, but your session has expired..." }, JsonRequestBehavior = JsonRequestBehavior.AllowGet};
} else {
base.HandleUnauthorizedRequest(filterContext);
}
}
最后,我有一个全局jquery ajaxSuccess处理程序,它测试我上面的消息,并警告用户该问题,然后强制重新加载(这应该导致MVC重定向到Login页面),
$(document).ajaxSuccess(function (result) {
if (result.ajaxUnauthorizedMessage) {
alert(result.ajaxUnauthorizedMessage);
location.reload();
}
});
不幸的是,它似乎没有这样的方式。相反的是会话开始“注销”,然后执行[授权]修饰的操作方法(由于依赖于丢失的会话而失败)。
令人困惑的是,如果我然后对同一个Ajax操作进行SECOND调用(不等待新会话的超时),则第二个调用被“HandleUnauthorizedRequest”方法拦截,然后一切正常,因为我预期第一个一个(好吧,并非每一个,ajaxSuccess全局处理程序都无法接收第二个调用,即使在捕获第一个调用之后,但在解决主要问题后需要担心这一点。)
此外,即使没有ajax也可以看到相同的行为。注销会触发,但我已经预先授权了,所以无论如何都会触发此行动。
我如何成功取消授权,以便在我预期的时候触发“HandleUnauthorizedRequest”?
一时兴起,我编辑了Session_Start(),并删除了所有请求和响应Cookie。我很惊讶地发现,auth-required Action方法仍然会触发,更令人惊讶的是Cookies全都回来了!它们在删除后仍然存在!我猜Session_Start不处理真正的Request对象?嗯,无论如何都值得一试。
答案 0 :(得分:0)
我对此的看法与你的有点不同。以下是我的解决方案的工作原理:
我在Auth
上创建了一个AccountController
方法,该方法返回“true”或“false”的JSON响应
[AllowAnonymous]
[DoNotResetAuthCookie]
[OutputCache(NoStore=true, Duration=0)]
public JsonResult Auth()
{
return Json(Request.IsAuthenticated, JsonRequestBehavior.AllowGet);
}
我实施了您已实施的Session_Start()
。
最后,在我的javascript中,我会定期检查是否仍然经过身份验证,如果没有,那么我重定向页面如下:
function redirectOnNotAuthorized(authUrl, redirectUrl) {
$.get(authUrl)
.done(function (data) {
var isStillAuthorized = data || false;
if (!isStillAuthorized) {
window.location.href = redirectUrl;
}
})
.fail(function () {
window.location.href = redirectUrl;
});
}
$(function() {
var timer, duration;
duration = 20000;
window.stillAuthorized = function stillAuthorized() {
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(stillAuthorized, duration);
redirectOnNotAuthorized("Account/Auth", "Account/LogOn");
};
timer = setTimeout(stillAuthorized, duration);
});
<强> EDIT1 强>:
我学到了一些东西......在redirectOnNotAuthorized
函数中它也可以设置
windows.location.reload()
而不是
windows.location.href = redirectUrl;
从而简化了代码并减少了对应用程序的依赖。