У меня была такая же проблема, и мне пришлось использовать пользовательский атрибут в MVC. Вы можете легко адаптировать это для работы в веб-формах, вы можете переопределить авторизацию ваших страниц на базовой странице, если все ваши страницы наследуются от некоторой базовой страницы (глобальный атрибут в MVC позволяет то же самое - переопределить метод OnAuthorization для всех контроллеров / действий в приложение)
Вот как выглядит атрибут:
public class AjaxAuthorizationAttribute : FilterAttribute, IAuthorizationFilter
{
public void OnAuthorization(AuthorizationContext filterContext)
{
if (filterContext.HttpContext.Request.IsAjaxRequest()
&& !filterContext.HttpContext.User.Identity.IsAuthenticated
&& (filterContext.ActionDescriptor.GetCustomAttributes(typeof(AuthorizeAttribute), true).Count() > 0
|| filterContext.ActionDescriptor.ControllerDescriptor.GetCustomAttributes(typeof(AuthorizeAttribute), true).Count() > 0))
{
filterContext.HttpContext.SkipAuthorization = true;
filterContext.HttpContext.Response.Clear();
filterContext.HttpContext.Response.StatusCode = (int)System.Net.HttpStatusCode.Unauthorized;
filterContext.Result = new HttpUnauthorizedResult("Unauthorized");
filterContext.Result.ExecuteResult(filterContext.Controller.ControllerContext);
filterContext.HttpContext.Response.End();
}
}
}
Обратите внимание, что вам нужно вызвать HttpContext.Response.End (); или ваш запрос будет перенаправлен на вход в систему (из-за этого я потерял некоторые волосы).
На стороне клиента я использовал метод jQuery ajaxError:
var lastAjaxCall = { settings: null, jqXHR: null };
var loginUrl = "yourloginurl";
//...
//...
$(document).ready(function(){
$(document).ajaxError(function (event, jqxhr, settings) {
if (jqxhr.status == 401) {
if (loginUrl) {
$("body").prepend("<div class='loginoverlay'><div class='full'></div><div class='iframe'><iframe id='login' src='" + loginUrl + "'></iframe></div></div>");
$("div.loginoverlay").show();
lastAjaxCall.jqXHR = jqxhr;
lastAjaxCall.settings = settings;
}
}
}
}
Это показывало вход в iframe через текущую страницу (похоже, что пользователь был перенаправлен, но вы можете изменить его), и когда вход был успешным, это всплывающее окно было закрыто, и исходный запрос ajax повторно отправлялся:
if (lastAjaxCall.settings) {
$.ajax(lastAjaxCall.settings);
lastAjaxCall.settings = null;
}
Это позволяет вашим пользователям входить в систему по окончании сеанса, не теряя при этом свою работу или данные, набранные в последней показанной форме.