ASP.NET MVC Global or BaseController ActionFilter to execute before OnAuthorization

In my application (ASP.NET MVC 3), I have a BaseController class that all my controllers inherit from, and in this BaseController I overridden the OnActionExecuting method to verify that the Session variable is populated, because I need access to it in all other action methods in the application. I also have a custom Authorize attribute that I defined that extends AuthorizeAttributeClass. In this attribute, I override OnAuthorization to check the same session variable that I load in the OnActionExecuting BaseController method to see if the user is allowed 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; } } } } 

User Authorization 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 OnActionExecuting BaseController method is running AFTER the OnAuthorization method in my AuthorizeByPermission attribute, and I need it in a different way, since BaseController should redistribute the Session variable if it does not exist before the authorize attribute tries to access it.

Basically, I need to find a way to have a base class method or global filter that can be registered before the OnAuthorization method starts. Any ideas on how to do this?

I tried registering GlobalFilter to load the session variable and set its Order property lower than the AuthorizeByPermission attribute, but this does not work either.

I also tried to override the Execute method in BaseController and actually quit before the custom authorization attribute, but the problem was that I did not have access to filterContext, which allowed me to redirect the user to the SignIn page if we were unable to load the session variable.

According to bmosh comment, I tried to turn my OnActionExecuting BaseController method into a separate filter and decorate BaseController with this attribute with a lower order number than the AuthorizeByPermission attribute, but it still doesn'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 configuration, the AuthorizeByPermission attribute is activated first.

Any ideas?

+4
source share
1 answer

You can try to override OnAuthorization instead of OnActionExecuting in your base controller.

+4
source

All Articles