Custom authentication filter in ASP.NET MVC
First, I approached this by trying to implement the IAuthorizationFilter interface. THis provides an OnAuthorization method that can be implemented for your custom authentication (see example below). However, as I realized , this is unnecessary. You can use the existing implementation of IAuthorizationFilter (the AuthorizeFilter class). Subclass that base class and simply override the AuthorizeCore method. This latter method is also the Microsoft recommended way of writing custom authorization code. That is/was the purpose behind making that method virtual.
In the example below, the custom part is – to check if the user’s account is LOCKED OUT for any reason. This LOCK OUT would be indicated by a TRUE value for the user’s ChangePassword value. If the user IS locked out, he is redirected to the LOGIN screen.
ORIGINAL APPROACH (implement IAuthorizationFilter , implement OnAuthorization) public class CustomAuthorizeAttribute : FilterAttribute, IAuthorizationFilter { public UserManager<ApplicationUser> UserManager { get; private set; } public void OnAuthorization(AuthorizationContext filterContext) { var user = filterContext.HttpContext.User; var applicationUser = UserManager.FindById(user.Identity.GetUserId()); if (applicationUser != null) { Route r = RouteTable.Routes.MapRoute( "loginRoute", // Route name "{Account}/{Login}", // URL with parameters new { controller = "Account", action = "Login" } ); if (applicationUser.ChangePassword.Value) filterContext.RequestContext.HttpContext.Response.RedirectToRoute(r); } } }
BETTER APPROACH (inherit from AuthorizeAttribute and override the AuthorizeCore method)
// The custom authorization attribute public class CustomAuthorizeAttribute : AuthorizeAttribute { public new UserRole Roles; // Notice the "new" protected override bool AuthorizeCore(HttpContextBase httpContext) { // call the base method base.AuthorizeCore(httpContext); // Generally authenticated to the site if (!httpContext.User.Identity.IsAuthenticated) return false; //Now , perform your custom authentication if (applicationUser.ChangePassword.Value) filterContext.RequestContext.HttpContext.Response.RedirectToRoute(r); return true; } }
To use this new CustomAuthorize Attribute, simply Replace [Authorize] with [CustomAuthorize]
[CustomAuthorize]
public class AccountController : Controller { ...
}
RESULT- Now, this custom authorization will kick in at the Controller level – every action method that is invoked will need to pass this authorization check (user’s account should not be locked out).
Summary
There are many different ways to implement custom authorization in asp.net MVC. This article described two different ways – with the latter approach (inherit from the base AuthorizeAttribute and override AuthorizeCore ) being the recommended approach.
Leave a Reply