Handling Unauthorised Ajax Requests in ASP.NET MVC App

The following post describes an application-wide method of handling unauthorised Ajax posts within an ASP.NET MVC application.

Modifying the Authorize attribute as per the example below shows how HandleUnauthorizedRequest can be overridden, returning a Ajax401Response when using Ajax. You’re then able to intercept all requests using jQuery and process them accordingly.

Custom Authorize Attribute


using System.Web;
using System.Web.Mvc;
namespace MyApplication.Attributes {
///
/// Custom authorisation attribute to return 401 request when Ajax request posted and user session has expired
///
public class AjaxAuthoriseAttribute: AuthorizeAttribute {
private class Ajax401Response: ActionResult {
// Called by the MVC framework to run the action result using the specified controller context
public override void ExecuteResult(ControllerContext context) {
context.HttpContext.Response.StatusCode = 401; // The request requires user authentication
context.HttpContext.Response.Write("Please log out and back in again to continue"); // HTTP response
context.HttpContext.Response.End();
}
}

///
/// Overriding AuthorizeCore as an entry point for custom auth from base controller
///
/// The HTTP context, which encapsulates all HTTP-specific information about an individual HTTP request.
///
protected override bool AuthorizeCore(HttpContextBase httpContext) {
if (!_authorisable) // When _authorise is false, don't perform authorisation
return true;

var result = base.AuthorizeCore(httpContext);

return result;
}

///
/// Encapsulates the information for using AuthorizeAttribute. The filterContext object contains the controller, HTTP context, request context, action result, and route data.
///
///
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) {
if (filterContext.RequestContext.HttpContext.Request.IsAjaxRequest()) {
filterContext.Result = new Ajax401Response(); // return 401 - unauthorised
} else base.HandleUnauthorizedRequest(filterContext);
}

private readonly bool _authorisable;

public AjaxAuthoriseAttribute() {
_authorisable = true;
}

// AjaxAuthorise can be turned on in any base controller if required
// Switch it off with this constructor
public AjaxAuthoriseAttribute(bool authorisable) {
_authorisable = authorisable;
}
}
}

You can then handle the response on the client side using jQuery


var errorMessageThrottlerEnabled = false;
$(document).ready(
function() {
$("body").ajaxError(
function(e, request) {
if (request.status == 401) {
if (errorMessageThrottlerEnabled)
alert(request.responseText);
window.location = '/SSO/LogOff';
errorMessageThrottlerEnabled = true;
}
}
);
}
);

Leave a Reply