我希望重用我当前定义的Controller / Action Authorize属性来指定用户访问角色以显示菜单项(因此用户只能看到他们有权访问的菜单项)。
目前,菜单项和控制器/动作授权属性角色的显示是不同的,因此任何更改都需要在两个地方进行更新,这可能在将来容易出错。
我一直在研究自定义授权属性,这是我到目前为止所做的:
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基本上由菜单项可用的用户角色,前端显示的文本标签以及控制器和动作的URL组成。 MenuItems在局部视图中呈现,具体取决于当前用户是否具有显示MenuItem所需的角色。
从我所看到的情况来看,我可能需要一份详尽的所有控制器操作列表以及在这两个区域中重用的相关用户角色,是否有更优雅的方法来实现这一目标?
答案 0 :(得分:3)
经过进一步研究,我偶然发现了AuthorizedActionLink nuget包。本质上,这是一个基于ActionLink的Html Helper,只有在用户有权访问目标控制器操作时才会显示链接(参见https://authorizedactionlink.codeplex.com/)。
然后,我只使用@Html.ActionLink()
而不是使用@Html.AuthorizedActionLink()
,而菜单是根据控制器/操作级别指定的用户权限构建的:)。
还有@Html.ActionIsAccessibleToUser(actionName, controllerName)
所以链接周围的标记,例如<li>
可以省略。
答案 1 :(得分:0)
最好的方法是将授权逻辑放到一个单独的类中,并在不同的地方使用它,例如CustomAuthorize,菜单项限制。这样就不会违反DRY。