In my application (ASP.NET MVC 3) I have a BaseController class that all my Controllers inherit and in that BaseController I have overridden the OnActionExecuting method to check to ensure a Session variable is populated as I need access to that in all other action methods in the application. I also have a custom Authorize attribute that I have defined that extends the AuthorizeAttributeClass. In that attribute I override OnAuthorization to check the same Session variable I am loading in the BaseController OnActionExecuting method to see if the user should be permitted to continue.
BaseController
public class BaseController : Controller
{
private ISessionUserService sessionUserService;
public BaseController(ISessionUserService sessionUserService)
{
this.sessionUserService = sessionUserService;
}
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
if (User != null && User.Identity.IsAuthenticated && this.sessionUserService.Current == null)
{
this.sessionUserService.Start(accountID, User.Identity.Name);
// If we weren't successful in reloading the SessionUser
// variable, redirect the user to the Sign In view
if (this.sessionUserService.Current == null)
{
filterContext.Result = new RedirectResult(Url.Action("SignIn", "Access", new { area = string.Empty }));
return;
}
}
}
}
Custom Authorize Attribute
public class AuthorizeByPermission : AuthorizeAttribute
{
public Permission[] Permissions { get; set; }
public AuthorizeByPermission(params Permission[] permissions)
{
this.Permissions = permissions;
}
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
SessionUser sessionUser = filterContext.HttpContext.Session.Get<SessionUser>();
if (sessionUser.HasPermission(Permissions))
return;
filterContext.Result = new HttpUnauthorizedResult();
}
}
The problem is that the BaseController OnActionExecuting method is firing AFTER the OnAuthorization method in my AuthorizeByPermission attribute and I need it to be the other way arround as the BaseController needs to popualte the Session variable if it isn't there before the authorize attribute attempts to access it.
Basically I need to find a way to have a base class method or a global filter that can be registered to occur before the OnAuthorization method fires. Any ideas on how to do this?
I have tried registering a GlobalFilter to load the session variable and set its Order property to be lower than the AuthorizeByPermission attribute but that didn't seem to work either.
I have also tried overriding the Execute method in the BaseController and that actually fired before the custom authorization attribute but the problem was that I didn't have access to the filterContext which allowed me to redirect the user to the SignIn page if we couldn't load the session variable.
As per bmosh's comment I tried turning my BaseController OnActionExecuting method into a separate filter and decorate the BaseController with that attribute with a lower Order number than the AuthorizeByPermission attribute but it still didn't work.
[FilterIWantToFireFirst(Order = 1)]
public class BaseController : Controller
{
}
public class AnotherController : BaseController
{
[AuthorizeByPermission(Permission.Add, Order = 2)]
public ActionResult SomeActionMethod()
{
}
}
Even with the above setup, the AuthorizeByPermission attribute is fired first.
Any ideas?
You could try overriding OnAuthorization instead of OnActionExecuting in your base controller.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With