6

我希望重用我当前定义的控制器/操作授权属性,这些属性指定用户访问角色以显示菜单项(因此用户只能看到他们有权访问的菜单项)。

目前菜单项的显示和控制器/动作授权属性角色是不同的,因此任何更改都需要在两个地方更新,这可能在未来容易出错。

我一直在研究自定义授权属性,这就是我目前所拥有的:

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 组成。MenuItem 会在部分视图中呈现,具体取决于当前用户是否具有显示 MenuItem 所需的角色。

据我所知,我可能需要一个详尽的列表,列出所有控制器操作和相关的用户角色,以便在这两个领域重用,有没有更优雅的方法来实现这一点?

4

2 回答 2

3

经过进一步研究,我偶然发现了 AuthorizedActionLink nuget 包。本质上,这是一个基于 ActionLink 的 Html Helper,只有在用户有权访问目标控制器操作时才会显示链接(请参阅https://authorizedactionlink.codeplex.com/)。

因此,我没有使用@Html.ActionLink(),而是简单地使用@Html.AuthorizedActionLink()并且菜单是根据在控制器/操作级别指定的用户权限构建的 :)。

链接周围还有@Html.ActionIsAccessibleToUser(actionName, controllerName)so标记,例如<li>可以省略's。

于 2013-08-13T14:27:36.703 回答
0

最好的方法是将授权逻辑放到一个单独的类中并在不同的地方使用它,例如CustomAuthorize、菜单项限制。这样就不会违反 DRY。

于 2013-08-05T15:18:33.490 回答