我有一个 ASP.Net MVC4 应用程序,其页面包含许多 Ajax 操作。我正在尝试处理会话到期后发生的事情。
目前,如果上下文报告当前请求已通过身份验证,我的代码会强制在 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 重定向到登录页面),
$(document).ajaxSuccess(function (result) {
if (result.ajaxUnauthorizedMessage) {
alert(result.ajaxUnauthorizedMessage);
location.reload();
}
});
不幸的是,它似乎不是那样工作的。取而代之的是会话开始“注销”,然后执行 [Authorize] 修饰的操作方法(然后由于对丢失会话的依赖而失败)。
令人费解的是,如果我随后对同一个 Ajax 操作进行第二次调用(不等待新会话的超时),第二次调用会被“HandleUnauthorizedRequest”方法拦截,然后一切都按我预期的那样工作(好吧,不是所有的,ajaxSuccess 全局处理程序都无法接收第二个调用,即使在捕获第一个调用之后也是如此,但在我解决了主要问题之后,这是需要担心的)。
此外,即使没有 ajax,也会看到相同的行为。注销会触发,但我是“预先授权的”,所以无论如何都会触发动作。
如何成功取消授权,以便“HandleUnauthorizedRequest”在我期望的时候触发?
编辑 1
一时兴起,我编辑了 Session_Start(),并让它删除了所有的请求和响应 Cookie。我惊讶地发现需要 auth 的 Action 方法仍然触发,更惊讶的是 Cookies 都回来了!他们在删除后仍然存在!我猜 Session_Start 不是在处理真正的 Request 对象?好吧,无论如何,值得一试。