Here is an attribute that I've created that can be used to direct to an unauthorized security action. it also allows you to specify a Reason which will be passed to the Unauthorized action on the Security controller, which you can then use for the view.
You can create any number of properties to customize this to fit your particular application, just make sure to add it to the RouteValueDictionary.
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public sealed class ApplySecurityAttribute : ActionFilterAttribute
{
private readonly Permission _permission;
public ApplySecurityAttribute(Permission permission)
: this(permission, string.Empty) {}
public ApplySecurityAttribute(Permission permission, string reason)
{
_permission = permission
Reason = reason;
}
public string Reason { get; set; }
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (!PermissionsManager.HasPermission(_permission)) // Put security check here
{
var routeValueDictionary = new RouteValueDictionary
{
{ "controller", "Security" }, // Security Controller
{ "action", "Unauthorized" }, // Unauthorized Action
{ "reason", Reason } // Put the reason here
};
filterContext.Result = new RedirectToRouteResult(routeValueDictionary);
}
base.OnActionExecuting(filterContext);
}
}
Here is the security controller
public class SecurityController : Controller
{
public ViewResult Unauthorized(string reason)
{
var vm = new UnauthorizedViewModel { Reason = reason };
return View(vm);
}
}
Here is the attribute declaration on a controller you wish to secure
[ApplySecurity(Permission.CanNuke, Reason = "You are not authorized to nuke!")]
Here is how PermissionsManager does the check to see if the user has the permissions
public static class PermissionsManager
{
public static bool HasPermission(EZTracPermission permission)
{
return HttpContext.Current.GetCurrentUser().Can(permission);
}
}