Reputation: 442
Our application is being migrated from WebForms to MVC. We have a different manner to handle with authorizations. A Database View is queried to verify an user authorization. This view returns, according to each user, all menu hierarchy. For example, if the User1 is trying to access a page named SecretList.aspx, a search is applied through the menu hierarchy (saved in HTTP Session after auth) to check the access authorization. If a menu item related with SecretList.aspx exists to that user, then the access is granted.
My question is, how to implement this approach in ASP.NET MVC 3?
I wouldn't like to put Attributes for each Controller Action and I've been read about Route Constraints and Custom Controller.
To Route Constraints, could I access the HTTP Session and retrieve my Menu Hierarchy for Authorization query?
To Custom Controller, which method should I consider overloading? Can I check authorization and redirect to another view, before Controller execute the complete Action code?
Any other better idea?
Upvotes: 3
Views: 610
Reputation: 3713
If you don't want to apply Attributes to your actions and keep access logic away from the Controllers and Actions definition, you can build a global action filter.
public class MenuAccessAttribute : ActionFilterAttribute
{
public override void OnActionExecuting (ActionExecutingContext filterContext)
{
var requestRoute = filterContext.RouteData.Route;
var currentUser = WebWorker.CurrentUser; // Or wathever is your thing to get the current user from session
if (currentUser != null && !MenuAccessService.UserHasAccessToRoute(currentUser, requestRoute))
{
filterContext.Result = new RedirectToRouteResult("MenuAccessDenied");
}
base.OnActionExecuting(filterContext);
}
}
Or something along these lines.
then, in global.asax Application_Start
GlobalFilters.Filters.Add(new MenuAccessAttribute());
But, if i were you, i'd spend some time adapting my access logic with asp.net mvc Roles, implementing a custom RoleProvider and decorating my controllers and actions with the right Authorize attributes.
Upvotes: 1
Reputation: 9189
I would use a custom Action Filter that is added globally to all actions, it would work very similarly to the built in Authorize Attribute. The action filter is run after routes have resolved and the controller is created (so anything passed to the controller must be constructable by any user) it can then check if the user can execute the action or if another ActionResult should be returned instead.
I would highly recommend looking at the MVC source (or using a tool like ILSpy) to view the code for the Authorize Attribute.
You could use a custom route constraint, but that would effectively mean the route doesn't exist for the user rather than they're not allowed access.
Upvotes: 2