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?
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.
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