9

I am trying to build a dynamic menu for my ASP.NET MVC4 web application. As I am constructing the menu I want to make sure that menu items for which a user should not have access are not displayed in the menu.

I am using forms authentication and the [Authorize] attribute with each page requiring a given a role.

Given two strings (Controller and Action), and a logged in user, how can I determine if a user will have access to that Controller Action?


All of my menu data is stored in a database. My plan to render the menu is to construct a JSON object of the menu data and embed that into the View. Then client side I will use Handlebars.js and plug the menu JSON object into a template.


What I am trying to do is check permissions on a given Controller/Action for a user as I am rendering the menu data. My initial thought was to use reflection and look up the controller action method and check for the existence of an Authorize attribute and check to see if the current logged in user has the necessary role access that page. If not, then the menu item would not be rendered.

I am always reluctant to use reflection however, there usually tends to be an easier way of doing things.

4

7 回答 7

1
public static IEnumerable<MethodInfo> GetActions(string controller, string action)
{
    return Assembly.GetExecutingAssembly().GetTypes()
           .Where(t =>(t.Name == controller && typeof(Controller).IsAssignableFrom(t)))
           .SelectMany(
                type =>
                type.GetMethods(BindingFlags.Public | BindingFlags.Instance)
                    .Where(a => a.Name == action && a.ReturnType == typeof(ActionResult))
             );

}

然后

var roles = ((AuthorizeAttribute) (GetActions("ControllerName" + "Controller", "ActionName").First().GetCustomAttributes(typeof (AuthorizeAttribute), false)[0])).Roles;
if(roles.Contains("admin or smth"))
{
        doSomsing();
}
于 2014-08-14T11:18:54.463 回答
0

创建名为 Rolevalidation 的类并添加如下代码

public class AuthorizeRoles : AuthorizeAttribute
{
    List<string> roles = new List<string>(“your list of roles”);
    bool isAuthenticated = false;
    for (int i = 0; i < roles.Count(); i++)
    {
        if (u.Role.Name == roles[i])
        {
            isAuthenticated = true;
            break;
        }
    }


    if (isAuthenticated)
    {
        SetCachePolicy(filterContext);
    }
    else
    {
        filterContext.Result = new RedirectResult("~/Error");
    }
}

在每个控制器的开头添加此代码* [AuthorizeRoles(Roles = "SuperAdmin")]

于 2014-02-17T07:41:47.150 回答
0

我已经实现了一个非常相似的场景。唯一的区别是我的菜单存储在 XML 文件中。

由于您将菜单数据存储在数据库中,我建议您在每个菜单记录中添加一个包含安全信息的 xml 字段;或者,有一个将菜单项映射到用户的新表。该表可能如下所示:

MenuItemName (id)             User
---------------------------------------
ViewVacationHistory (12)      firstuser
ViewVacationHistory (12)      seconduser
ApproveVacationRequest (10)   seconduser

现在,当您的控制器接收到将导致显示菜单项的请求时,并且由于您的控制器使用 Authorize 属性进行装饰,它将在 HttpContext 中接收用户。在这里,您只需在数据库中查询匹配的菜单项,然后相应地呈现菜单。

于 2013-05-22T08:12:00.083 回答
0

假设您有一个包含所有菜单 html 代码的视图,使用以下方法可能会更好:

<ul class="menu">
    <li>
        @Html.ActionLink("Home", "Index", "Home")
    </li>
    @if (System.Web.Security.Roles.IsUserInRole(User.Identity.Name, "Administrator"))
    {
        <li>
            @Html.ActionLink("Statistics", "Index", "Stats")
        </li>
    }
</ul>

希望这可以帮助!

于 2014-09-05T14:05:16.790 回答
0

使用 ActionFilter 属性根据角色过滤用户 http://www.asp.net/mvc/tutorials/hands-on-labs/aspnet-mvc-4-custom-action-filters

于 2013-12-01T09:21:37.817 回答
0

链接将由来自动作和控制器的 json 对象生成。

json 对象应该有一个链接列表(或实现菜单项所需的内容),该列表应该由存储在数据库中的各种设置生成,告诉每个用户要显示哪些链接。

除此之外,如果用户有 URL 那么在这种情况下你需要使用

https://msdn.microsoft.com/en-us/library/system.web.mvc.authorizeattribute.users(v=vs.118).aspx

于 2014-04-03T10:09:17.447 回答
-1

您可以使用 Authorize 属性来装饰控制器的操作,[Authorize(AuthorizationContext)]也可以扩展 authorize 属性以进行自定义授权;

您还可以在字典中定义一些约定,在其中定义控制器的 Create 操作需要创建类型授权 aso

Dictionary<string, Right> actionConventions = new Dictionary<string, Right>
    {
        { "Index", Right.View },
        { "List", Right.View },
        { "Open", Right.View },
        { "Create", Right.Create},
        { "Edit", Right.Edit },
        { "Delete", Right.Delete }
}

如果操作遵守字典中定义的约定,则覆盖OnAuthorizationAuthorize方法,或者检查约定,或者检查您为操作或.AuthorizeAttributeAuthorize(AuthorizationContext)HandleUnauthorizedRequest(AuthorizationContext)

处理菜单,您可以创建一个授权服务,在该服务中返回当前用户的权限并添加一个包含用户权限的类,并在渲染模型时检查模型,是否应该渲染菜单项。

授权属性 MSDN

于 2013-01-17T15:39:42.660 回答