ASP.NET MVC Filter Based Authorization
We may use action filters for authorization in an ASP.NET MVC application. An action filter is an attribute that we can apply to a controller action or an entire controller.
The ASP.NET MVC framework includes several action filters including OutputCache, HandleError, and Authorize. Authorize action filter enables us to restrict access to a particular user or role.
Authorization filters implements the IAuthorizationFilter attribute. Authorization filters are used to implement authentication and authorization for controller actions. The ASP.NET MVC framework includes a base ActionFilterAttribute class. This class implements both the IActionFilter and IResultFilter interfaces and inherits from the Filter class.
The base ActionFilterAttribute class has the following methods that to override:
File: Utils/AuthorizeAppAttribute.cs
using System.Web.Mvc;
using System.Linq;
namespace Utils
{
public class AuthorizeAppAttribute: AuthorizeAttribute
{
// set the View in case of unauthorized access
public AuthorizeAppAttribute()
{
View = "UnAuthorized";
}
// view name
public string View { get; set; }
/// <summary>
/// Check for Authorization
/// </summary>
/// <param name="filterContext"></param>
public override void OnAuthorization(AuthorizationContext filterContext)
{
isUserAuthorized(filterContext);
}
/// <summary>
/// Method to check if the user is Authorized or not
/// if yes continue to perform the action else redirect to error page
/// </summary>
/// <param name="filterContext"></param>
private void isUserAuthorized(AuthorizationContext filterContext)
{
if (filterContext.HttpContext.User.Identity.IsAuthenticated)
{
if (checkAuthorization(filterContext))
return;
var vr = new ViewResult();
vr.ViewName = View;
ViewDataDictionary dict = new ViewDataDictionary();
dict.Add("Message", "You are not authorized to use this page...");
vr.ViewData = dict;
var result = vr;
filterContext.Result = result;
}
}
/// <summary>
/// Check for authorization
/// Group membership for the user should match with the ControllerName and Role
/// we may check for authorization from Active Directory, LDAP or Database
/// </summary>
/// <param name="filterContext"></param>
/// <returns>is user authorized for resource</returns>
private bool checkAuthorization(AuthorizationContext filterContext)
{
try
{
string actionName = filterContext.RouteData.Values["action"].ToString();
string controllerName = filterContext.RouteData.Values["controller"].ToString();
string username = filterContext.HttpContext.User.Identity.Name.Replace("DOMAIN\\", "");
// we may check for authorization from Active Directory, LDAP or Database
// lets use database for demo
var db = new Data.AppDataContext();
var oAuth = db.Authorizations.Where(a => a.Username.Equals(username) && a.Control.Equals(controllerName) && a.Action.Equals(actionName)).FirstOrDefault();
if (oAuth != null)
{
// if the user role satisfies one of the authorization role specified for the action then he/she is authorized
string[] arrRoles = this.Roles.Split(',');
if (arrRoles.Contains(oAuth.Role))
return true;
}
}
catch (System.Exception e)
{
// handle the exception
}
return false;
}
}
}
If the user is unauthorized for the resource, the view for unauthorized access will be displayed.
Therefore we need a view for unauthorized access:
File: Views/Shared/UnAuthorized.cshtml
@{
ViewBag.Title = "Unauthorized Access";
}
<h2>@ViewBag.Title</h2>
@ViewData["Message"]
That's it for filter based authorization.
Authorization using the AuthorizeAppAttribute filter should be as follows:
using System.Web.Mvc;
using Utils;
namespace FilterBasedAuthorization.Controllers
{
// we may set authorization at controller level
//[AuthorizeApp(Roles = "Staff")]
public class SampleController : Controller
{
// no authorization
public ActionResult Index()
{
return View();
}
// or we may set authorization at action level
[AuthorizeApp(Roles = "Admin, Manager, Staff")]
public ActionResult StaffIndex()
{
return View();
}
[AuthorizeApp(Roles = "Manager")]
public ActionResult ManagerIndex()
{
return View();
}
}
}
The ASP.NET MVC framework includes several action filters including OutputCache, HandleError, and Authorize. Authorize action filter enables us to restrict access to a particular user or role.
Authorization filters implements the IAuthorizationFilter attribute. Authorization filters are used to implement authentication and authorization for controller actions. The ASP.NET MVC framework includes a base ActionFilterAttribute class. This class implements both the IActionFilter and IResultFilter interfaces and inherits from the Filter class.
The base ActionFilterAttribute class has the following methods that to override:
- OnActionExecuting – called before a controller action is executed.
- OnActionExecuted – called after a controller action is executed.
- OnResultExecuting – called before a controller action result is executed.
- OnResultExecuted – called after a controller action result is executed.
File: Utils/AuthorizeAppAttribute.cs
using System.Web.Mvc;
using System.Linq;
namespace Utils
{
public class AuthorizeAppAttribute: AuthorizeAttribute
{
// set the View in case of unauthorized access
public AuthorizeAppAttribute()
{
View = "UnAuthorized";
}
// view name
public string View { get; set; }
/// <summary>
/// Check for Authorization
/// </summary>
/// <param name="filterContext"></param>
public override void OnAuthorization(AuthorizationContext filterContext)
{
isUserAuthorized(filterContext);
}
/// <summary>
/// Method to check if the user is Authorized or not
/// if yes continue to perform the action else redirect to error page
/// </summary>
/// <param name="filterContext"></param>
private void isUserAuthorized(AuthorizationContext filterContext)
{
if (filterContext.HttpContext.User.Identity.IsAuthenticated)
{
if (checkAuthorization(filterContext))
return;
var vr = new ViewResult();
vr.ViewName = View;
ViewDataDictionary dict = new ViewDataDictionary();
dict.Add("Message", "You are not authorized to use this page...");
vr.ViewData = dict;
var result = vr;
filterContext.Result = result;
}
}
/// <summary>
/// Check for authorization
/// Group membership for the user should match with the ControllerName and Role
/// we may check for authorization from Active Directory, LDAP or Database
/// </summary>
/// <param name="filterContext"></param>
/// <returns>is user authorized for resource</returns>
private bool checkAuthorization(AuthorizationContext filterContext)
{
try
{
string actionName = filterContext.RouteData.Values["action"].ToString();
string controllerName = filterContext.RouteData.Values["controller"].ToString();
string username = filterContext.HttpContext.User.Identity.Name.Replace("DOMAIN\\", "");
// we may check for authorization from Active Directory, LDAP or Database
// lets use database for demo
var db = new Data.AppDataContext();
var oAuth = db.Authorizations.Where(a => a.Username.Equals(username) && a.Control.Equals(controllerName) && a.Action.Equals(actionName)).FirstOrDefault();
if (oAuth != null)
{
// if the user role satisfies one of the authorization role specified for the action then he/she is authorized
string[] arrRoles = this.Roles.Split(',');
if (arrRoles.Contains(oAuth.Role))
return true;
}
}
catch (System.Exception e)
{
// handle the exception
}
return false;
}
}
}
If the user is unauthorized for the resource, the view for unauthorized access will be displayed.
Therefore we need a view for unauthorized access:
File: Views/Shared/UnAuthorized.cshtml
@{
ViewBag.Title = "Unauthorized Access";
}
<h2>@ViewBag.Title</h2>
@ViewData["Message"]
That's it for filter based authorization.
Authorization using the AuthorizeAppAttribute filter should be as follows:
using System.Web.Mvc;
using Utils;
namespace FilterBasedAuthorization.Controllers
{
// we may set authorization at controller level
//[AuthorizeApp(Roles = "Staff")]
public class SampleController : Controller
{
// no authorization
public ActionResult Index()
{
return View();
}
// or we may set authorization at action level
[AuthorizeApp(Roles = "Admin, Manager, Staff")]
public ActionResult StaffIndex()
{
return View();
}
[AuthorizeApp(Roles = "Manager")]
public ActionResult ManagerIndex()
{
return View();
}
}
}
Comments
Post a Comment