My web app has many partial views in a single page that are loaded using Ajax.
I want all Ajax requests to redirect the user to the login page when his session/cookie is expired instead of the login page being loaded into each partial view container. The web app is using Forms authentication.
I've implemented this solution and it works fine for the most part.
The problem is that the redirect doesn't work when the user refreshes a Kendo grid that uses Ajax binding. I see the redirect request in the network tab but nothing happens. I've tried implementing a custom Authorize attribute and changing the http status code but the ASP.NET framework won't redirect if the code isn't 401. How can I make the redirect work?
Here is my custom Authorize attribute that isn't working. I'm not sure if using a custom attribute is the right solution.
public class AuthorizeUserAttribute : AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
if (filterContext.HttpContext.Request.IsAjaxRequest())
{
if (filterContext.HttpContext.Request.IsAuthenticated)
{
filterContext.Result = new HttpStatusCodeResult(System.Net.HttpStatusCode.Forbidden);
}
else
{
filterContext.Result = new HttpStatusCodeResult(System.Net.HttpStatusCode.Unauthorized);
}
//filterContext.Result = new HttpStatusCodeResult(System.Net.HttpStatusCode.InternalServerError);
//filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { controller = "account", action = "logon" }));
}
else
{
base.HandleUnauthorizedRequest(filterContext);
}
}
}
The code you posted above will work as long as the mvc pipeline is active. The problem is those ajax calls can bypass your pipeline altogether for various reasons, an ajax call does not constitute a full postback in the same manner as a form post does. Perhaps you can look into global ajax handlers and check for the presence of authentication or lack thereof and redirect as needed. As far as I recall, these handlers are called prior to any of "lower down" result handlers.
$(document).ajaxError(function (event, jqxhr, settings, data) {
...
});
$(document).ajaxSuccess(function (event, jqxhr, settings, exception) {
...
});