Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reuse MVC Controller Roles Authorization for Display of Menu Items

I'm looking to reuse my currently defined Controller/Action Authorize attributes that specify user access roles for display of menu items (so a user only sees the menu items they have access to).

Currently the display of menu items and the controller/action authorize attribute roles are distinct, so any changes would require updating in two places, which may be prone to error in the future.

I have been looking into Custom Authorize Attributes, and this is what I have so far:

public class MyAuthorizeAttribute : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        var isAuthorized = base.AuthorizeCore(httpContext);
        if (!isAuthorized)
        {
            return false;
        }

        var routeData = httpContext.Request.RequestContext.RouteData;
        string currentAction = routeData.GetRequiredString("action");
        string currentController = routeData.GetRequiredString("controller");

        var currentUserRoles = GetCurrentUserRoles();

        // from the list of menu items, find the menu item with the current action
        // and controller and check the current user's roles entitle access
    }

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        filterContext.Result = new RedirectToRouteResult(
            new RouteValueDictionary(
                new
                {
                    controller = "Error",
                    action = "Unauthorised"
                })
            );
    }
}

MenuItems are essentially consisted of the user roles the menu item is available to, a textual label for frontend display and the url from the controller and action. The MenuItems are rendered in a partial view depending on if the current user is in the required role to display the MenuItem.

From what I can see, I may need an exhaustive list of all controller actions and the associated user roles to be reused in both areas, is there a more elegant way of achieving this?

like image 394
Richard Pursehouse Avatar asked Aug 05 '13 15:08

Richard Pursehouse


1 Answers

After further research, I stumbled upon the AuthorizedActionLink nuget package. Essentially this is a Html Helper based on ActionLink, which will only display links if the user has access to the target controller action (see https://authorizedactionlink.codeplex.com/).

So then rather than using @Html.ActionLink(), I simply use @Html.AuthorizedActionLink() and the menu is built from user privileges specified at the controller/action level :).

There is also @Html.ActionIsAccessibleToUser(actionName, controllerName) so markup surrounding the links, such as <li>'s can be omitted.

like image 75
Richard Pursehouse Avatar answered Oct 02 '22 21:10

Richard Pursehouse