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